注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

北漂的小羊

Java编程,开发者,程序员,软件开发,编程,代码。新浪微博号:IT国子监

 
 
 

日志

 
 
关于我

在这里是面向程序员的高品质IT技术学习社区,是程序员学习成长的地方。让我们更好地用技术改变世界。请关注新浪微博号: IT国子监(http://weibo.com/itguozijian)

网易考拉推荐

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

2012-12-22 19:31:54|  分类: spring |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

Spring 事务配置的几种方式及应用举例


环境: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. <!-- 前面的 dataSource等配置略 ........ -->  
  2.   
  3. <!-- 事务管理器 -->  
  4. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
  5. <property name="dataSource">  
  6. <ref local="dataSource" />  
  7. </property>  
  8. </bean>  
  9.   
  10. <!-- 事务模板 -->  
  11. <bean id="baseTransactionProxy"  
  12. class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"  
  13. abstract="true">  
  14. <property name="transactionManager" ref="transactionManager" />  
  15. <property name="transactionAttributes">  
  16. <props>  
  17. <prop key="*">PROPAGATION_REQUIRED</prop>   <!-- 本文仅简单用一种方式说明。所有方法起事务,可以修改以精细和区别性控制事务 -->  
  18. </props>  
  19. </property>  
  20. </bean>  
  21.   
  22.   
  23. <!-- 业务对象 -->  
  24. <bean id="authService" parent="baseTransactionProxy">  
  25. <property name="target">  
  26. <bean class="com.xxxx.cms.service.AuthorityService">  
  27. <property name="authDao" ref="authDao" />  
  28. </bean>  
  29. </property>  
  30. </bean>  
  31. <bean id="departmentService" parent="baseTransactionProxy">  
  32. <property name="target">  
  33. <bean class="com.xxxx.cms.service.pojo.DepartmentService">  
  34. <property name="departmentDao" ref="departmentDao" />  
  35. </bean>  
  36. </property>  
  37. </bean>  
  38. <!-- 数据访问对象 -->  
  39. <bean id="authDao" class="com.xxxx.cms.dao.jdbc.AuthorityDao">  
  40. <property name="dataSource" ref="dataSource" />  
  41. </bean>  
  42. <bean id="departmentDao" class="com.xxxx.cms.dao.jdbc.DepartmentDao">  
  43. <property name="dataSource" ref="dataSource" />  
  44. </bean>  


  这种代理工厂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 的所有方法进行事务控制。   

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
  <property name="sessionFactory">
   <ref local="sessionFactory" />
  </property> 
 </bean> 


 

Xml代码 
  1. <!-- 事务管理拦截器 -->   
  2. <bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">   
  3. <property name="transactionManager">   
  4. <ref local="transactionManager"/>   
  5. </property>   
  6. <property name="transactionAttributes">   
  7. <props>   
  8. <prop key="*">PROPAGATION_REQUIRED</prop> <!-- 本文仅简单用一种方式说明。所有方法起事务,还可以精细控制事务 -->   
  9. </props>   
  10. </property>   
  11. </bean>   
  12.   
  13. <!-- 配置要拦截哪些方法 -->   
  14. <bean id="trasactionMethodPointcutAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">   
  15. <property name="mappedNames">   
  16. <list>   
  17. <value>*</value> <!-- 所有方法 -->   
  18. </list>   
  19. </property>   
  20. <property name="advice">   
  21. <ref local="transactionInterceptor" />   
  22. </property>   
  23. </bean>   
  24.   
  25. <!-- 配置要拦截哪些类,并使用那些拦截器 -->   
  26. <bean id="ServiceAutoProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">   
  27. <property name="proxyTargetClass" value="true"></property>   
  28. <property name="beanNames">   
  29. <list>   
  30. <value>*Service</value>   
  31. </list>   
  32. </property>   
  33. <property name="interceptorNames">   
  34. <list>    
  35. <!-- 头三个是我们项目中用的其他 Advisor,这里展示了添加拦截器进行aspect控制的灵活性。省略他们的配置 -->   
  36. <value>monitorMethodPointcutAdvisor</value>   
  37. <value>asynmonitorMethodPointcutAdvisor</value>   
  38. <value>businessLogMethodPointcutAdvisor</value>   
  39. <value>trasactionMethodPointcutAdvisor</value> <!-- 事务拦截器, 直接配成 transactionInterceptor 去掉 trasactionMethodPointcutAdvisor bean 也可以, -->   
  40. </list>   
  41. </property>   
  42. </bean>   

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

Xml代码 
  1. <!-- 业务对象 -->   
  2. <bean class="com.xxxx.cms.service.AuthorityService">   
  3. <property name="authDao" ref="authDao" />   
  4. </bean>   
  5. <bean class="com.xxxx.cms.service.pojo.DepartmentService">   
  6. <property name="departmentDao" ref="departmentDao" />   
  7. </bean>   
  8.   
  9. <!-- 数据访问对象 -->   
  10. <bean id="authDao" class="com.xxxx.cms.dao.jdbc.AuthorityDao">   
  11. <property name="dataSource" ref="dataSource" />   
  12. </bean>   
  13. <bean id="departmentDao" class="com.xxxx.cms.dao.jdbc.DepartmentDao">   
  14. <property name="dataSource" ref="dataSource" />   
  15. </bean>   

 
    代码中的使用方式不变,同 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; }   

 
   结合 <tx:annotation-driven/>配置。


它实际是将 xml 中的

Java代码 
  1. <property name="transactionAttributes">   
  2. <props>   
  3. <prop key="*">PROPAGATION_REQUIRED</prop> <!-- 所有方法起事务,还可以精细控制事务 -->   
  4. </props>   
  5. </property>   

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

 

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

  评论这张
 
阅读(511)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2016