Spring 的Hibernate事务管理机制 .

来源:互联网 发布:电脑关机软件 编辑:程序博客网 时间:2024/06/05 21:16
一、事务的隔离级别
使用Spring 声明式事务时,有一个非常重要的概念就是事务属性。事务属性通常由事务的传播行为,事务的隔离级别,事务的超时值和事务只读标志组成。
org.springframework.transaction包里面的TransactionDefinition
getTimeout()方法,它返回事务必须在多少秒内完成。
isReadOnly(),事务是否只读,事务管理器能够根据这个返回值进行优化,确保事务是只读的。
getIsolationLevel()方法返回事务的隔离级别,事务管理器根据它来控制另外一个事务可以看到本事务内的哪些数据。

在TransactionDefinition接口中定义了四个不同的事务隔离级别:

1) ISOLATION_DEFAULT 这是一个 PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别(读未提交).另外四个与JDBC的隔离级别相对应

2) ISOLATION_READ_UNCOMMITTED这是事务最低的隔离级别,它充许别外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读。

3) ISOLATION_READ_COMMITTED 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。这种事务隔离级别可以避免脏读出现,但是可能会出现不可重复读和幻像读。

4) ISOLATION_REPEATABLE_READ 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)

 

二、事务的传播性质
定义了关于客户端和被调用方法的事务边界。传播规则就是在说明新的事务是否要被启动或是挂起,或者方法是否要在事务环境中运行。
在TransactionDefinition接口中定义了七个事务传播行为:

1) PROPAGATION_REQUIRED 如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务;

2) PROPAGATION_SUPPORTS 如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行;

3) PROPAGATION_MANDATORY 如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异;

4)PROPAGATION_REQUIRES_NEW 总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起;

5) PROPAGATION_NOT_SUPPORTED总是非事务地执行,并挂起任何存在的事务;

6) PROPAGATION_NEVER总是非事务地执行,如果存在一个活动事务,则抛出异常;

7) PROPAGATION_NESTED如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务, 则按 TransactionDefinition.PROPAGATION_REQUIRED 属性执行;

 

三、Spring 声明式事务
(1) 利用拦截器来管理事务
 <!-- 事务管理器 -->
 

[java] view plaincopyprint?
  1. <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">  
  2.      <property name="sessionFactory">  
  3.          <ref bean="sessionFactory"/>  
  4.      </property>  
  5.  </bean>  
 
 <!-- 事务拦截器,激活事务管理器所必须的bean -->
[java] view plaincopyprint?
  1. <bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">   
  2.        <property name="transactionManager">   
  3.            <ref bean="transactionManager" />   
  4.        </property>    
  5.        <!-- 配置事务属性 -->   
  6.       <property name="transactionAttributes">   
  7.           <props>   
  8.              <prop key="delete*">PROPAGATION_REQUIRED</prop>   
  9.              <prop key="add*">PROPAGATION_REQUIRED</prop>   
  10.              <prop key="update*">PROPAGATION_REQUIRED</prop>   
  11.              <prop key="save*">PROPAGATION_REQUIRED</prop>   
  12.              <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>   
  13.           </props>   
  14.        </property>   
  15. </bean>   
  16. <!--BeanNameAutoProxyCreator是个根据bean名生成自动代理的代理创建器,该bean通常需要接受两个参数。一个是指定需要代理的bean,另一个是代理bean所需的事务拦截器 -->  
  17. <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">  
  18.  <!-- 可以是Service或DAO层(最好是针对业务层*Service) -->  
  19. <property name="beanNames">  
  20.  <list>  
  21.   <value>*Service</value>  
  22.  </list>  
  23. </property>  
  24.  <property name="interceptorNames">  
  25.   <list>  
  26.    <value>transactionInterceptor</value>  
  27.   </list>  
  28.  </property>  
  29. </bean>  
 

(2) 利用AOP 方式管理事务
 在Spring中声明式的事务管理是用Spring的AOP来实现的。了解了这些后我们要考虑的是我们的事务到底要加在那一层,
 在我们的项目中往往将事务加到serivce层,这样做的好是:比如在DAO层我有三个方法来对数据进行操作,而我们的一次业务逻辑,
 需要我们要调用这三个方法才能完成这个一业务而这三方法还要放到一个事务中去,
 我们要是将事务配在DAO层我们做法只有将这三个方法分别加上一个事务,这显然违背了我们的业务需求。
 而在我们的service层中可以用一个方法来调用Dao层中的这三个方法,这样我们只要将serive层中的这个方法加上一个事务控制,
 我们业务需求就很容易的解决了。所以我们将事务大多数的要加在service层上。
 

[java] view plaincopyprint?
  1. <!-- 以AspectJ方式 定义 AOP -->  
  2.  <aop:config proxy-target-class="true">  
  3.       <aop:advisor pointcut="execution(* com.*.service.impl.*Manager*.*(..))" advice-ref="txAdvice" />  
  4.  </aop:config>  
  5.   
  6.  <!-- 基本事务定义,使用transactionManager作事务管理,默认get*方法的事务为readonly,其余方法按默认设置. -->  
  7.  <tx:advice id="txAdvice" transaction-manager="transactionManager">  
  8.   <tx:attributes>  
  9.    <tx:method name="get*" read-only="true" />  
  10.    <tx:method name="find*" read-only="true" />  
  11.    <tx:method name="del*" propagation="REQUIRED" rollback-for="Exception">  
  12.    <tx:method name="save*" propagation="REQUIRED" rollback-for="Exception">  
  13.    <tx:method name="update*" propagation="REQUIRED" rollback-for="Exception">  
  14.   </tx:attributes>  
  15.  </tx:advice>  

 
0 0
原创粉丝点击