梦之天堂

我学故我知,我思故我在;java你我,happy你我——sylilzy

BlogJava 首页 新随笔 联系 聚合 管理
  3 Posts :: 8 Stories :: 2 Comments :: 0 Trackbacks
spring的事务处理详解:调用一个方法前的事务处理过程(源代码分析)
 
sylilzy@163.com
版权所有,转载请注明出处
 
实际上,在spring的事务中,只要该类被设置为了事务代理:
 
拦截器都会创建一个TransactionInfo 对象:
 
TransactionInfo txInfo = new TransactionInfo(txAttr, method);
 
 
而且如果 只要被调用的方法设置了事务属性(txAttr),不管是什么属性都会调用:
 
txInfo.newTransactionStatus(this.transactionManager.getTransaction(txAttr));
 
根据该方法的事务属性(definition )的不同,this.transactionManager.getTransaction(txAttr)的返回值会有所不同(代码见AbstractPlatformTransactionManager),具体为以下几种情况:
1.当前没有事务时(即以下代码中的((HibernateTransactionObject) transaction).hasTransaction()返回false),会返回以下几种:
 
 1 //  Check definition settings for new transaction.
 2    if  (definition.getTimeout()  <  TransactionDefinition.TIMEOUT_DEFAULT)  {
 3     throw   new  InvalidTimeoutException( " Invalid transaction timeout " , definition.getTimeout());
 4   }

 5
 6    //  No existing transaction found -> check propagation behavior to find out how to behave.
 7    if  (definition.getPropagationBehavior()  ==  TransactionDefinition.PROPAGATION_MANDATORY)  {
 8     throw   new  IllegalTransactionStateException(
 9       " Transaction propagation 'mandatory' but no existing transaction found " );
10   }

11    else   if  (definition.getPropagationBehavior()  ==  TransactionDefinition.PROPAGATION_REQUIRED  ||
12     definition.getPropagationBehavior()  ==  TransactionDefinition.PROPAGATION_REQUIRES_NEW  ||
13       definition.getPropagationBehavior()  ==  TransactionDefinition.PROPAGATION_NESTED)  {
14     if  (debugEnabled)  {
15     logger.debug( " Creating new transaction with name [ "   +  definition.getName()  +   " ] " );
16    }

17    doBegin(transaction, definition);
18     boolean  newSynchronization  =  ( this .transactionSynchronization  !=  SYNCHRONIZATION_NEVER);
19     return  newTransactionStatus(definition, transaction,  true , newSynchronization, debugEnabled,  null );
20   }

21    else   {
22     //  Create "empty" transaction: no actual transaction, but potentially synchronization.
23     boolean  newSynchronization  =  ( this .transactionSynchronization  ==  SYNCHRONIZATION_ALWAYS);
24     return  newTransactionStatus(definition,  null false , newSynchronization, debugEnabled,  null );
25   }

26
2.当前有事务时
 1 private  TransactionStatus handleExistingTransaction(
 2    TransactionDefinition definition, Object transaction,  boolean  debugEnabled)
 3     throws  TransactionException  {
 4
 5    if  (definition.getPropagationBehavior()  ==  TransactionDefinition.PROPAGATION_NEVER)  {
 6     throw   new  IllegalTransactionStateException(
 7       " Transaction propagation 'never' but existing transaction found " );
 8   }

 9
10    if  (definition.getPropagationBehavior()  ==  TransactionDefinition.PROPAGATION_NOT_SUPPORTED)  {
11     if  (debugEnabled)  {
12     logger.debug( " Suspending current transaction " );
13    }

14    Object suspendedResources  =  suspend(transaction);
15     boolean  newSynchronization  =  ( this .transactionSynchronization  ==  SYNCHRONIZATION_ALWAYS);
16     return  newTransactionStatus(
17      definition,  null false , newSynchronization, debugEnabled, suspendedResources);
18   }

19
20    if  (definition.getPropagationBehavior()  ==  TransactionDefinition.PROPAGATION_REQUIRES_NEW)  {
21     if  (debugEnabled)  {
22     logger.debug( " Suspending current transaction, creating new transaction with name [ "   +
23       definition.getName()  +   " ] " );
24    }

25    Object suspendedResources  =  suspend(transaction);
26    doBegin(transaction, definition);
27     boolean  newSynchronization  =  ( this .transactionSynchronization  !=  SYNCHRONIZATION_NEVER);
28     return  newTransactionStatus(
29      definition, transaction,  true , newSynchronization, debugEnabled, suspendedResources);
30   }

31
32    if  (definition.getPropagationBehavior()  ==  TransactionDefinition.PROPAGATION_NESTED)  {
33     if  ( ! isNestedTransactionAllowed())  {
34      throw   new  NestedTransactionNotSupportedException(
35        " Transaction manager does not allow nested transactions by default -  "   +
36        " specify 'nestedTransactionAllowed' property with value 'true' " );
37    }

38     if  (debugEnabled)  {
39     logger.debug( " Creating nested transaction with name [ "   +  definition.getName()  +   " ] " );
40    }

41     if  (useSavepointForNestedTransaction())  {
42      //  Create savepoint within existing Spring-managed transaction,
43      //  through the SavepointManager API implemented by TransactionStatus.
44      //  Usually uses JDBC 3.0 savepoints. Never activates Spring synchronization.
45     DefaultTransactionStatus status  =
46       newTransactionStatus(definition, transaction,  false false , debugEnabled,  null );
47     status.createAndHoldSavepoint();
48      return  status;
49    }

50     else   {
51      //  Nested transaction through nested begin and commit/rollback calls.
52      //  Usually only for JTA: Spring synchronization might get activated here
53      //  in case of a pre-existing JTA transaction.
54     doBegin(transaction, definition);
55      boolean  newSynchronization  =  ( this .transactionSynchronization  !=  SYNCHRONIZATION_NEVER);
56      return  newTransactionStatus(definition, transaction,  true , newSynchronization, debugEnabled,  null );
57    }

58   }

59
最后,txInfo被绑定到当前线程上作为当前事务:
 
txInfo.bindToThread()
 
然后,调用实际的目标类的方法并捕捉异常:
 
try   {
   
//  This is an around advice.
   
//  Invoke the next interceptor in the chain.
   
//  This will normally result in a target object being invoked.
   retVal  =  invocation.proceed();
  }

  
catch  (Throwable ex)  {
   
//  target invocation exception
   doCloseTransactionAfterThrowing(txInfo, ex);
   
throw  ex;
  }

  
finally   {
   doFinally(txInfo);
  }

  doCommitTransactionAfterReturning(txInfo);
  
return  retVal;
 }

另外一点,TransactionInfo的newTransactionStatus调用时如果参数的不是null,TransactionInfo.hasTransaction()方法返回true;
 
重要提示:
在spring中创建的事务代理类并是目标类的超类,只是一个实现这目标类接口的类,该类会调用目标类的方法,所在如果一个目标类中的方法调用自身的另一个事务方法,另一个方法只是作为普通方法来调用,并不会加入事务机制

参考资料:
1.Spring Reference Manual:http://static.springframework.org/spring/docs/1.2.x/reference/index.html
2.Spring API doc:http://static.springframework.org/spring/docs/1.2.x/api/index.html
3.Spring 的源代码

作者简介:
    施祖阳,网名sylilzy,1979年生。
    2002年起从事软件开发工作,主要研究为JAVA、Linux及相关技术。
    你可通过 sylilzy@163.com 与作者联系。
 
 
 
posted on 2006-06-14 18:34 sylilzy 阅读(1081) 评论(0)  编辑  收藏 所属分类: Java

只有注册用户登录后才能发表评论。


网站导航: