Spring 事务机制详解(2)

(2)PROPAGATION_SUPPORTS 如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行。但是对于事务同步的事务管理器,PROPAGATION_SUPPORTS与不使用事务有少许不同。

Java代码:
            //事务属性 PROPAGATION_REQUIRED
 methodA(){
  methodB();
 }

//事务属性 PROPAGATION_SUPPORTS
 methodB(){
  ……
}

单纯的调用methodB时,methodB方法是非事务的执行的。当调用methdA时,methodB则加入了methodA的事务中,事务地执行。

(3)PROPAGATION_MANDATORY 如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。

Java代码:

//事务属性 PROPAGATION_REQUIRED
    methodA(){
  methodB();
                }

//事务属性 PROPAGATION_MANDATORY
    methodB(){
    ……
    }

当单独调用methodB时,因为当前没有一个活动的事务,则会抛出异常throw new IllegalTransactionStateException("Transaction propagation 'mandatory' but no existing transaction found");当调用methodA时,methodB则加入到methodA的事务中,事务地执行。

(4)PROPAGATION_REQUIRES_NEW 总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。

Java代码:

//事务属性 PROPAGATION_REQUIRED
 methodA(){
    doSomeThingA();
 methodB();
 doSomeThingB();
 }

//事务属性 PROPAGATION_REQUIRES_NEW
 methodB(){
    ……
}

Java代码:

main(){
  methodA();
 }

相当于

Java代码:

main(){
  TransactionManager tm = null;
 try{
  //获得一个JTA事务管理器
    tm = getTransactionManager();
    tm.begin();//开启一个新的事务
    Transaction ts1 = tm.getTransaction();
    doSomeThing();
    tm.suspend();//挂起当前事务
    try{
      tm.begin();//重新开启第二个事务
      Transaction ts2 = tm.getTransaction();
      methodB();
      ts2.commit();//提交第二个事务
  }
  Catch(RunTimeException ex){
      ts2.rollback();//回滚第二个事务
  }
  finally{
      //释放资源
  }
    //methodB执行完后,复恢第一个事务
    tm.resume(ts1);
 doSomeThingB();
    ts1.commit();//提交第一个事务
}
catch(RunTimeException ex){
    ts1.rollback();//回滚第一个事务
}
finally{
    //释放资源
}
 }

在这里,我把ts1称为外层事务,ts2称为内层事务。从上面的代码可以看出,ts2与ts1是两个独立的事务,互不相干。Ts2是否成功并不依赖于 ts1。如果methodA方法在调用methodB方法后的doSomeThingB方法失败了,而methodB方法所做的结果依然被提交。而除了 methodB之外的其它代码导致的结果却被回滚了。使用PROPAGATION_REQUIRES_NEW,需要使用 JtaTransactionManager作为事务管理器。
 (5)PROPAGATION_NOT_SUPPORTED  总是非事务地执行,并挂起任何存在的事务。使用PROPAGATION_NOT_SUPPORTED,也需要使用JtaTransactionManager作为事务管理器。(代码示例同上,可同理推出)

(6)PROPAGATION_NEVER 总是非事务地执行,如果存在一个活动事务,则抛出异常;

(7)PROPAGATION_NESTED如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务, 则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行。这是一个嵌套事务,使用JDBC 3.0驱动时,仅仅支持DataSourceTransactionManager作为事务管理器。需要JDBC 驱动的java.sql.Savepoint类。有一些JTA的事务管理器实现可能也提供了同样的功能。使用PROPAGATION_NESTED,还需要把PlatformTransactionManager的nestedTransactionAllowed属性设为true;而 nestedTransactionAllowed属性值默认为false;

Java代码:

//事务属性 PROPAGATION_REQUIRED
 methodA(){
    doSomeThingA();
    methodB();
    doSomeThingB();
 }

//事务属性 PROPAGATION_NESTED
 methodB(){
  ……
}

如果单独调用methodB方法,则按REQUIRED属性执行。如果调用methodA方法,相当于下面的效果:

Java代码:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/829a7d2b245de431c93b79abfe4a7aa8.html