Spring 事务简化配置

转载 2007年10月08日 10:26:00

在 spring 中, 事务管理一般是通过声明一个 txProxyTemplate, 然后业务 bean 中 parent = "txProxyTemplate", 这样做未免显得有些繁琐, 并且如果业务 bean 还需要其他拦截器, 配置也不太方便, 下面贴出我的配置, 用 DefaultAdvisorAutoProxyCreator 实现自动代理

 

代码
  1. <beans>  
  2.     <!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->  
  3.     <bean id="transactionManager"  
  4.           class="org.springframework.orm.hibernate3.HibernateTransactionManager">  
  5.           <property name="sessionFactory">  
  6.               <ref bean="sessionFactory"/>  
  7.           </property>  
  8.     </bean>    
  9.        
  10.     <bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">  
  11.         <property name="transactionManager" ref="transactionManager"/>  
  12.         <property name="transactionAttributeSource">  
  13.           <value>  
  14.             com.skyon.user.manager.UserManager.*=PROPAGATION_REQUIRED   
  15.             #Add new defines here ->  
  16.           </value>  
  17.         </property>  
  18.     </bean>  
  19.        
  20.     <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">  
  21.         <property name="interceptorNames">  
  22.             <list>  
  23.                 <value>transactionInterceptor</value>  
  24.                 <!--  
  25.                 增加新的 Interceptor  
  26.                 -->  
  27.             </list>  
  28.         </property>  
  29.     </bean>  
  30.   
  31.     <bean class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor">  
  32.       <property name="transactionInterceptor" ref="transactionInterceptor"/>  
  33.     </bean>  
  34.            
  35. </beans>  
  36.   

 

这里利用 DefaultAdvisorAutoProxyCreator 实现了对容器中所有 bean 的自动代理, 增加一个需要事务的业务 bean 时只要在 transactionInterceptor 增加一行即可, 增加别的 interceptor 也非常方便,
极大减少了配置量 

 

 

完整版来叻!!

配置Spring,针对Service层的bean做事务处理,以往的做法是这样:

代码
  1. <bean id="txProxyTemplate" abstract="true"    
  2. class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">    
  3.     <property name="transactionManager">  
  4.         <ref bean="transactionManager"/>  
  5.     </property>    
  6.     <property name="transactionAttributes">    
  7.         <props>  
  8.             <prop key="find*">PROPAGATION_REQUIRED, readOnly</prop>    
  9.             <prop key="*">PROPAGATION_REQUIRED</prop>    
  10.         </props>    
  11.     </property>    
  12. </bean>    
  13.   
  14. <bean id="userManager" parent="txProxyTemplate">    
  15.     <property name="target">    
  16.         <bean class="some.package.UserManagerImpl">    
  17.             <property name="userDAO"><ref bean="userDAO"/></property>    
  18.         </bean>    
  19.     </property>    
  20. </bean>    
  21.   

 

以后,如果增加新的Service/Manager,则XML配置的增量是这一段:

代码
  1. <bean id="someOtherManager" parent="txProxyTemplate">    
  2.     <property name="target">    
  3.         <bean class="some.package.someOtherManagerImpl">    
  4.         </bean>    
  5.     </property>    
  6. </bean>    

 

上面说的是老的做法,比较传统。缺点是增量比较大,配置起来copy&paste让人觉得不太爽,比较臃肿。

下面的是Feiing给出的更好的方案,我有一些修改:

 

代码
  1. <beans>    
  2.         <!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->    
  3.     <bean id="transactionManager"           class="org.springframework.orm.hibernate3.HibernateTransactionManager">    
  4.           <property name="sessionFactory">    
  5.               <ref bean="sessionFactory"/>    
  6.           </property>    
  7.     </bean>           
  8.            
  9.         <bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">    
  10.             <property name="transactionManager" ref="transactionManager"/>    
  11.             <property name="transactionAttributes">  
  12.                 <props>  
  13.                     <prop key="*">PROPAGATION_REQUIRED</prop>  
  14.                     <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>  
  15.                 </props>  
  16.             </property>  
  17.         </bean>    
  18.            
  19.         <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">    
  20.                 <property name="beanNames">  
  21.                     <value>*Service,*Manager</value>  
  22.                 </property>  
  23.                 <property name="interceptorNames">    
  24.                         <list>    
  25.                                 <value>transactionInterceptor</value>    
  26.                                 <!--   
  27.                                 此处增加新的Interceptor  
  28.                                 -->    
  29.                         </list>    
  30.                 </property>    
  31.         </bean>    
  32.   
  33.         <bean class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor">    
  34.           <property name="transactionInterceptor" ref="transactionInterceptor"/>    
  35.         </bean>    
  36.   
  37.         <bean id="userManager" class="some.package.UserManagerImpl" autoWire="byName"/>  
  38.                    
  39. </beans>    

 

以后每次的增量是这一段:

代码
  1. <bean id="userManager" class="some.package.UserManagerImpl" autoWire="byName"/>   

 

跟配置普通bean的方法一样,非常简洁、直观。对现有的Service接口也无须任何修改

我把Feiing的transactionAttributesSource改成叻transactionAttributes,并且将DefaultAdvisorAutoProxyCreator改成了BeanNameAutoProxyCreator,我觉得毕竟不是context下的每个bean都需要事务,只要在Service层做AOP就可以叻。

和Robbin一致认为,Feiing的做法非常可取,因为它分离叻XML配置文件关注点

完整版来叻!!
下面的是Feiing给出的更好的方案,我有一些修改:

 

 

代码
  1. <beans>    
  2.         <!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->    
  3.     <bean id="transactionManager"           class="org.springframework.orm.hibernate3.HibernateTransactionManager">    
  4.           <property name="sessionFactory">    
  5.               <ref bean="sessionFactory"/>    
  6.           </property>    
  7.     </bean>           
  8.            
  9.         <bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">    
  10.             <property name="transactionManager" ref="transactionManager"/>    
  11.             <property name="transactionAttributes">  
  12.                 <props>  
  13.                     <prop key="*">PROPAGATION_REQUIRED</prop>  
  14.                     <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>  
  15.                 </props>  
  16.             </property>  
  17.         </bean>    
  18.            
  19.         <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">    
  20.                 <property name="beanNames">  
  21.                     <value>*Service,*Manager</value>  
  22.                 </property>  
  23.                 <property name="interceptorNames">    
  24.                         <list>    
  25.                                 <value>transactionInterceptor</value>    
  26.                                 <!--   
  27.                                 此处增加新的Interceptor  
  28.                                 -->    
  29.                         </list>    
  30.                 </property>    
  31.         </bean>    
  32.   
  33.         <bean class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor">    
  34.           <property name="transactionInterceptor" ref="transactionInterceptor"/>    
  35.         </bean>    
  36.   
  37.         <bean id="userManager" class="some.package.UserManagerImpl" autoWire="byName"/>  
  38.                    
  39. </beans>    

 

以后每次的增量是这一段:

代码
  1. <bean id="userManager" class="some.package.UserManagerImpl" autoWire="byName"/>   

 

跟配置普通bean的方法一样,非常简洁、直观。对现有的Service接口也无须任何修改

我把Feiing的transactionAttributesSource改成叻transactionAttributes,并且将DefaultAdvisorAutoProxyCreator改成了BeanNameAutoProxyCreator,我觉得毕竟不是context下的每个bean都需要事务,只要在Service层做AOP就可以叻。

和Robbin一致认为,Feiing的做法非常可取,因为它分离叻XML配置文件关注点

 

受hongliang启发,我现在就用这个方法,但是发现一个Bug。里面代理匹配的名字有*Manager,就是想匹配所有的ManagerObject。但是好像没有注意到,这样配置会把transactionManager也匹配上,然后定义的是find以外的方法都是要事务的。也就说transactionManager执行getTransaction的时候还会要事务,然后就是死循环,造成溢出。。

我解决的办法就是transactionManager改称transactionManagerHibernate。这么做的时候一定要注意名字的问题。别一不小心,把一个不相关的东东给弄进来的。。。

对了,加Acegi的时候有很多*Manager,打算想一个比较好名字匹配。。

我所有的Service层都是*Service,我从来不用*Manager的。。。怪不得我的没问题

举报

相关文章推荐

Spring事务支持:利用继承简化配置

原文链接:http://www.cnblogs.com/jbelial/archive/2012/06/04/2533531.html      因为事务代理的实现类是 TransactionP...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)