Bob@CSDN

Be good,Do right

Spring 事务简化配置

在 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给出的更好的方案,我有一些修改:

 

 

代码
<beans>             <!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->         <bean id="transactionManager"           class="org.springframework.orm.hibernate3.HibernateTransactionManager">               <property name="sessionFactory">                   <ref bean="sessionFactory"/>               </property>         </bean>                                <bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">                 <property name="transactionManager" ref="transactionManager"/>                 <property name="transactionAttributes">                   <props>                       <prop key="*">PROPAGATION_REQUIRED</prop>                       <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>                   </props>               </property>           </bean>                         <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">                     <property name="beanNames">                       <value>*Service,*Manager</value>                   </property>                   <property name="interceptorNames">                             <list>                                     <value>transactionInterceptor</value>                                     <!--                                    此处增加新的Interceptor                                   -->                             </list>                     </property>             </bean>                <bean class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor">               <property name="transactionInterceptor" ref="transactionInterceptor"/>             </bean>                <bean id="userManager" class="some.package.UserManagerImpl" autoWire="byName"/>                       </beans>    

 

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

代码
<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
想对作者说点什么? 我来说一句

Spring 事务配置

2011年07月20日 3KB 下载

spring 事务配置

2011年10月15日 9KB 下载

Spring事务配置的五种方式

2009年08月21日 103KB 下载

spring声明事务配置

2009年03月15日 48KB 下载

Spring事务配置的五种方式

2010年05月08日 102KB 下载

Spring 事务代理配置

2011年10月15日 12KB 下载

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭