您的位置:首页 > 编程语言 > Java开发

spring事务处理:调用一个方法前的事务处理过程

2014-12-23 14:03 519 查看
实际上,在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;
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐