技术开发 频道

Spring声明式事务管理源码解读


有了上面的简单介绍就可以进入真正判断是否需要事务的地方了。这个方法在TransactionAspectSupport类里,

 

代码
 
  1. /**  
  2.      * Create a transaction if necessary.  
  3.      * @param method method about to execute  
  4.      * @param targetClass class the method is on  
  5.      * @return a TransactionInfo object, whether or not a transaction was created.  
  6.      * The hasTransaction() method on TransactionInfo can be used to tell if there  
  7.      * was a transaction created.  
  8.      */  
  9.     protected TransactionInfo createTransactionIfNecessary(Method method, Class targetClass) {   
  10.         // If the transaction attribute is null, the method is non-transactional.   
  11.         final TransactionAttribute sourceAttr =   
  12.                 this.transactionAttributeSource.getTransactionAttribute(method, targetClass);//就是在这里判断了这个方法的事务属性   
  13.         TransactionAttribute txAttr = sourceAttr;   
  14.   
  15.         // If no name specified, apply method identification as transaction name.   
  16.         if (txAttr != null && txAttr.getName() == null) {   
  17.             final String name = methodIdentification(method);   
  18.             txAttr = new DelegatingTransactionAttribute(sourceAttr) {   
  19.                 public String getName() {   
  20.                     return name;   
  21.                 }   
  22.             };   
  23.         }   
  24.   
  25.         TransactionInfo txInfo = new TransactionInfo(txAttr, method);   
  26. //TransactionInfo是TransactionAspectSupport的一个内部类,它的主要功能是记录方法和对应的事务属性   
  27.         if (txAttr != null) {   
  28.             // We need a transaction for this method   
  29.             if (logger.isDebugEnabled()) {   
  30.                 logger.debug("Getting transaction for " + txInfo.joinpointIdentification());   
  31.             }   
  32.   
  33.             // The transaction manager will flag an error if an incompatible tx already exists   
  34.             txInfo.newTransactionStatus(this.transactionManager.getTransaction(txAttr));//这个方法要仔细的看   
  35.         }   
  36.         else {   
  37.             // The TransactionInfo.hasTransaction() method will return   
  38.             // false. We created it only to preserve the integrity of   
  39.             // the ThreadLocal stack maintained in this class.   
  40.             if (logger.isDebugEnabled())   
  41.                 logger.debug("Don't need to create transaction for [" + methodIdentification(method) +   
  42.                         "]: this method isn't transactional");   
  43.         }   
  44.   
  45.         // We always bind the TransactionInfo to the thread, even if we didn't create   
  46.         // a new transaction here. This guarantees that the TransactionInfo stack   
  47.         // will be managed correctly even if no transaction was created by this aspect.   
  48.         txInfo.bindToThread();   
  49.         return txInfo;   
  50.     }  

TransactionInfo是TransactionAspectSupport的一个内部类,它的主要功能是记录方法和对应的事务属性,在上面这个方法的最后,这个TransactionInfo对象被保存到当前线程中。

 

而这个方法会在事务拦截器TransactionInterceptor中被调用,TransactionInterceptor实际上是TransactionAspectSupport的子类,看看其中的invoke方法:

代码
 
  1. // Work out the target class: may be <code>null</code>.   
  2.         // The TransactionAttributeSource should be passed the target class   
  3.         // as well as the method, which may be from an interface   
  4.         Class targetClass = (invocation.getThis() != null) ? invocation.getThis().getClass() : null;   
  5.            
  6.         // Create transaction if necessary.   
  7.         TransactionInfo txInfo = createTransactionIfNecessary(invocation.getMethod(), targetClass);   
  8.   
  9.         Object retVal = null;   
  10.         try {   
  11.             // This is an around advice.   
  12.             // Invoke the next interceptor in the chain.   
  13.             // This will normally result in a target object being invoked.   
  14.             retVal = invocation.proceed();   
  15.         }   
  16.         catch (Throwable ex) {   
  17.             // target invocation exception   
  18.             doCloseTransactionAfterThrowing(txInfo, ex);   
  19.             throw ex;   
  20.         }   
  21.         finally {   
  22.             doFinally(txInfo);   
  23.         }   
  24.         doCommitTransactionAfterReturning(txInfo);//在这里执行方法结束之后需要的操作   
  25.         return retVal;  

这个方法就如同一般的interceptor需要实现的方法一样。只不过在这个方法里判断被反射的方法是否需要事务。
0
相关文章