Spring 事务配置的几种方式及应用举例(转载)

来源:百度文库 编辑:神马文学网 时间:2024/04/29 10:41:12
环境:JDK 1.4.x , Hibernate 3.1, Spring 2.0.6, 开发模式: Service + DAO

1. 代理工厂Bean事务管理( *ProxyFactoryBean) + Service + DAO配置

    我刚开始看Spring时用的书是林信良的《Spring技术手册》,书中对声明式事务主要采用 TransactionProxyFactoryBean,业务Bean如 Service或BO类继承它来进行事务控制。代理工厂Bean( *ProxyFactoryBean)这一类Spring提供的工厂类,可将一个 bean 进行委托代理,从而达到控制方法行为的目的。

   此类事务配置一般如下(因为我们未采用这种方式,就以书上的JDBC datasource举例说明。不同公司采用的格式可能有所不同):
Xml代码
  1.   
  2.   
  3.   
  4.  id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
  5.  name="dataSource">  
  6.  local="dataSource" />  
  7.   
  8.   
  9.   
  10.   
  11.  id="baseTransactionProxy"  
  12. class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"  
  13. abstract="true">  
  14.  name="transactionManager" ref="transactionManager" />  
  15.  name="transactionAttributes">  
  16.   
  17.  key="*">PROPAGATION_REQUIRED     
  18.   
  19.   
  20.   
  21.   
  22.   
  23.   
  24.  id="authService" parent="baseTransactionProxy">  
  25.  name="target">  
  26.  class="com.xxxx.cms.service.AuthorityService">  
  27.  name="authDao" ref="authDao" />  
  28.   
  29.   
  30.   
  31.  id="departmentService" parent="baseTransactionProxy">  
  32.  name="target">  
  33.  class="com.xxxx.cms.service.pojo.DepartmentService">  
  34.  name="departmentDao" ref="departmentDao" />  
  35.   
  36.   
  37.   
  38.   
  39.  id="authDao" class="com.xxxx.cms.dao.jdbc.AuthorityDao">  
  40.  name="dataSource" ref="dataSource" />  
  41.   
  42.  id="departmentDao" class="com.xxxx.cms.dao.jdbc.DepartmentDao">  
  43.  name="dataSource" ref="dataSource" />  
  44.   


  这种代理工厂Bean的事务管理一般都要求将 Service 的 bean 配置为 class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" , 上面的例子使用了 parent="baseTransactionProxy" 继承机制简化了原书中的配置。

   代码中通过以下方式使用:
 

  

Java代码
  1. AuthService authService = (AuthService) context.getBean("authService");    
  2.     boolean b = authService.hasPermission("TOKEN_XXXXX");   

 

2. 自动代理事务(*AutoProxyCreator) + Service + DAO配置

    *AutoProxyCreator这一类东东,能够自动为Spring容器中的bean进行 AOP 代理,配置起来能适当简化。一般需要用 BeanNameAutoProxyCreator 来配置对那些类进行自动代理, MethodPointcutAdvisor 来配置对哪些方法进行代理。

    这种声明式事务配置采用拦截器(Interceptor)或通知器(Advisor) 进行事务控制,这里使用了Spring提供的 TransactionInterceptor 来管理事务。 (本质上 ProxyFactoryBean 也要生成被代理对象的字节码,不过每个类型的ProxyFactoryBean 只能固定处理一个 Aspect,不算真正的AOP)。

    以下配置对 *Service 的所有方法进行事务控制。   


  
   
  

 
 


 

Xml代码
  1.     
  2.  id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">    
  3.  name="transactionManager">    
  4.  local="transactionManager"/>    
  5.     
  6.  name="transactionAttributes">    
  7.     
  8.  key="*">PROPAGATION_REQUIRED     
  9.     
  10.     
  11.     
  12.   
  13.     
  14.  id="trasactionMethodPointcutAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">    
  15.  name="mappedNames">    
  16.     
  17. *     
  18.     
  19.     
  20.  name="advice">    
  21.  local="transactionInterceptor" />    
  22.     
  23.     
  24.   
  25.     
  26.  id="ServiceAutoProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">    
  27.  name="proxyTargetClass" value="true">    
  28.  name="beanNames">    
  29.     
  30. *Service    
  31.     
  32.     
  33.  name="interceptorNames">    
  34.      
  35.     
  36. monitorMethodPointcutAdvisor    
  37. asynmonitorMethodPointcutAdvisor    
  38. businessLogMethodPointcutAdvisor    
  39. trasactionMethodPointcutAdvisor     
  40.     
  41.     
  42.    

 
Service,DAO的配置方式稍微改变一下, Service不再作为ProxyFactoryBean的 target属性,而是一个顶级 bean,这样 Service bean看起来就更单纯一些。 

Xml代码
  1.     
  2.  class="com.xxxx.cms.service.AuthorityService">    
  3.  name="authDao" ref="authDao" />    
  4.     
  5.  class="com.xxxx.cms.service.pojo.DepartmentService">    
  6.  name="departmentDao" ref="departmentDao" />    
  7.     
  8.   
  9.     
  10.  id="authDao" class="com.xxxx.cms.dao.jdbc.AuthorityDao">    
  11.  name="dataSource" ref="dataSource" />    
  12.     
  13.  id="departmentDao" class="com.xxxx.cms.dao.jdbc.DepartmentDao">    
  14.  name="dataSource" ref="dataSource" />    
  15.    

 
    代码中的使用方式不变,同 1 小节。

3.  自动代理 +  Service DAO零配置

    这种是我们项目中运用的方式,transactionInterceptor,trasactionMethodPointcutAdvisor ,ServiceAutoProxyCreator 三个 bean的配置不变。
    Service,DAO 无需配置, 其原理参见我另一篇文章:

我的开发经验分享(一)-Spring业务bean零配置


    代码中的使用方式不同,使用 ServiceFactory 直接创建bean,代码如下: 
    

   

Java代码
  1. AuthService authService = (AuthService)ServiceFactory.createBean(AuthService.class);    
  2.     boolean b = authService.hasPermission("TOKEN_XXXXX");   

 
    ServiceFactory 内部会自动注册未注册的 bean, 并和Spring 容器和已配置的拦截器关联。
 

4. Annotation 声明事务

    如果是 JDK 1.5下,Spring 也支持 注释声明式事务,类似于如下代码(附部分片段):

Java代码
  1. @Transactional    
  2. public class PersonServiceImpl implements PersonService    
  3. private EntityManager em;    
  4.   
  5.    @PersistenceContext    
  6.   public void setEntityManager(EntityManager em)    
  7.   { this.em = em; }   

 
   结合 配置。


它实际是将 xml 中的

Java代码
  1. "transactionAttributes">    
  2.     
  3. "*">PROPAGATION_REQUIRED     
  4.     
  5.    

 
转移到了Java代码中,本质上是一样的,两种方式都能进行精细事务管理。不过个人不太偏好这种方式,因为xml更便于集中管理,修改后无需编译。

 

1.5下Spring还用哪种更简化的事务管理方式,鄙人不是太熟,欢迎大家分享。