【Spring实战】----Spring事务管理配置解析

上篇说了aop的配置,并且说了spring事务管理是基于aop的,那么Spring声明式事务的配置就有两种方式:XML配置及注解配置

不多说,直接看配置文件

一、配置文件

applicationContext-transaction.xml

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2.   
  3. <beans xmlns="http://www.springframework.org/schema/beans"  
  4.     xmlns:aop="http://www.springframework.org/schema/aop"   
  5.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  6.     xmlns:tx="http://www.springframework.org/schema/tx"  
  7.     xsi:schemaLocation="http://www.springframework.org/schema/beans   
  8.         http://www.springframework.org/schema/beans/spring-beans.xsd  
  9.         http://www.springframework.org/schema/aop   
  10.         http://www.springframework.org/schema/aop/spring-aop.xsd   
  11.         http://www.springframework.org/schema/tx   
  12.         http://www.springframework.org/schema/tx/spring-tx.xsd ">  
  13.           
  14.     <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">  
  15.         <property name="sessionFactory" ref="sessionFactory" />  
  16.     </bean>  
  17.       
  18.     <!-- 通知 -->  
  19.     <tx:advice id="txAdvice" transaction-manager="transactionManager">  
  20.         <tx:attributes>  
  21.             <!-- 传播行为 -->  
  22.             <tx:method name="save*" propagation="REQUIRED"/>  
  23.             <tx:method name="delete*" propagation="REQUIRED"/>  
  24.             <tx:method name="insert*" propagation="REQUIRED"/>  
  25.             <tx:method name="update*" propagation="REQUIRED"/>  
  26.             <tx:method name="list*" propagation="SUPPORTS" read-only="true"/>  
  27.             <tx:method name="get*" propagation="SUPPORTS" read-only="true"/>  
  28.         </tx:attributes>  
  29.     </tx:advice>  
  30.       
  31.     <!-- aop -->  
  32.     <aop:config>  
  33.         <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.mango.jtt.service.*.*(..))"/>  
  34.     </aop:config>  
  35.   
  36.     <!-- 注解管理事务 -->  
  37.     <tx:annotation-driven transaction-manager="transactionManager"/>  
  38. </beans>  


注解管理事务以上都是xml配置的事务,基于注解的事务,只需配置<tx:annotation-driven/>标签,然后在Spring bean中添加@Transational注解即可实现事务管理。


二,Spring事务管理本质

Spring并不直接管理事务,而是提供多种事务管理器,他们讲事务管理的职责委托给JAT或其他持久化机制所提供的平台相关的事务实现。上述配置文件中就是利用的hibernate事务管理器实现的Hibernate事务管理。详细信息不说,想事务属性什么的,具体可参考spring in action及spring官方文档


三、继续说下事务对getCurrentSession的影响

Spring实战篇系列----源码解析SessionFactory及Session的管理及getCurrentSession的使用文章中说了getCurrentSession是要基于事务的,才能实现session的生命周期的管理。那么Spring的事务管理到底做了什么。

首先看事务管理器HibernateTransactionManager,它并没有做太多工作,一个空的构造函数及

  1. /** 
  2.      * Create a new HibernateTransactionManager instance. 
  3.      * A SessionFactory has to be set to be able to use it. 
  4.      * @see #setSessionFactory 
  5.      */  
  6.     public HibernateTransactionManager() {  
  7.     }  

及afterPropertiesSet()方法

  1. @Override  
  2.     public void afterPropertiesSet() {  
  3.         if (getSessionFactory() == null) {  
  4.             throw new IllegalArgumentException("Property 'sessionFactory' is required");  
  5.         }  
  6.         if (this.entityInterceptor instanceof String && this.beanFactory == null) {  
  7.             throw new IllegalArgumentException("Property 'beanFactory' is required for 'entityInterceptorBeanName'");  
  8.         }  
  9.   
  10.         // Check for SessionFactory's DataSource.  
  11.         if (this.autodetectDataSource && getDataSource() == null) {  
  12.             DataSource sfds = SessionFactoryUtils.getDataSource(getSessionFactory());  
  13.             if (sfds != null) {  
  14.                 // Use the SessionFactory's DataSource for exposing transactions to JDBC code.  
  15.                 if (logger.isInfoEnabled()) {  
  16.                     logger.info("Using DataSource [" + sfds +  
  17.                             "] of Hibernate SessionFactory for HibernateTransactionManager");  
  18.                 }  
  19.                 setDataSource(sfds);  
  20.             }  
  21.         }  
  22.     }  


可见事务管理器的初始化并没有做太多工作。那么看事务管理对其的影响,先看调用栈

  1. TransactionSynchronizationManager.initSynchronization() line: 269     
  2. HibernateTransactionManager(AbstractPlatformTransactionManager).prepareSynchronization(DefaultTransactionStatus, TransactionDefinition) line: 542     
  3. HibernateTransactionManager(AbstractPlatformTransactionManager).prepareTransactionStatus(TransactionDefinition, Object, boolean, boolean, boolean, Object) line: 513      
  4. HibernateTransactionManager(AbstractPlatformTransactionManager).getTransaction(TransactionDefinition) line: 393   
  5. TransactionInterceptor(TransactionAspectSupport).createTransactionIfNecessary(PlatformTransactionManager, TransactionAttribute, String) line: 426     
  6. TransactionInterceptor(TransactionAspectSupport).invokeWithinTransaction(Method, Class<?>, InvocationCallback) line: 275    
  7. TransactionInterceptor.invoke(MethodInvocation) line: 96      
  8. ReflectiveMethodInvocation.proceed() line: 179    
  9. ExposeInvocationInterceptor.invoke(MethodInvocation) line: 92     
  10. ReflectiveMethodInvocation.proceed() line: 179    
  11. JdkDynamicAopProxy.invoke(Object, Method, Object[]) line: 213     
  12. $Proxy316.getOrderById(String) line: not available    
  13. OrderController.orderPay(String, Model) line: 84      

从调用栈可以看出,只要在连接点处配置了事务管理,首先都会走到initSynchronization()。

  1. /** 
  2.      * Activate transaction synchronization for the current thread. 
  3.      * Called by a transaction manager on transaction begin. 
  4.      * @throws IllegalStateException if synchronization is already active 
  5.      */  
  6.     public static void initSynchronization() throws IllegalStateException {  
  7.         if (isSynchronizationActive()) {  
  8.             throw new IllegalStateException("Cannot activate transaction synchronization - already active");  
  9.         }  
  10.         logger.trace("Initializing transaction synchronization");  
  11.         synchronizations.set(new LinkedHashSet<TransactionSynchronization>());  
  12.     }  

最终会在synchronizations中set进new LinkedHashSet<TransactionSynchronization>(),从而isSynchronizationActive()为true
  1. /** 
  2.      * Return if transaction synchronization is active for the current thread. 
  3.      * Can be called before register to avoid unnecessary instance creation. 
  4.      * @see #registerSynchronization 
  5.      */  
  6.     public static boolean isSynchronizationActive() {  
  7.         return (synchronizations.get() != null);  
  8.     }  


因此这里也就解释了上上篇留下的疑问,为什么配置了事务管理,就不会抛异常了。其实只有配置了事务,session就会在事务提交或者回滚后关闭

  1. SessionImpl.close() line: 402     
  2. SessionFactoryUtils.closeSession(Session) line: 167   
  3. SpringSessionSynchronization.afterCompletion(int) line: 138   
  4. TransactionSynchronizationUtils.invokeAfterCompletion(List<TransactionSynchronization>, int) line: 168      
  5. HibernateTransactionManager(AbstractPlatformTransactionManager).invokeAfterCompletion(List<TransactionSynchronization>, int) line: 1001     
  6. HibernateTransactionManager(AbstractPlatformTransactionManager).triggerAfterCompletion(DefaultTransactionStatus, int) line: 976   
  7. HibernateTransactionManager(AbstractPlatformTransactionManager).processCommit(DefaultTransactionStatus) line: 806     
  8. HibernateTransactionManager(AbstractPlatformTransactionManager).commit(TransactionStatus) line: 730   
  9. TransactionInterceptor(TransactionAspectSupport).commitTransactionAfterReturning(TransactionAspectSupport$TransactionInfo) line: 483      
  10. TransactionInterceptor(TransactionAspectSupport).invokeWithinTransaction(Method, Class<?>, InvocationCallback) line: 290    
  11. TransactionInterceptor.invoke(MethodInvocation) line: 96      
  12. ReflectiveMethodInvocation.proceed() line: 179    
  13. ExposeInvocationInterceptor.invoke(MethodInvocation) line: 92     
  14. ReflectiveMethodInvocation.proceed() line: 179    
  15. JdkDynamicAopProxy.invoke(Object, Method, Object[]) line: 213     
  16. $Proxy316.getOrderById(String) line: not available    
  17. OrderController.orderPayInfo(String, Model) line: 72      


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值