spring事务的7种传播行为

事务传播行为

什么叫事务传播行为?听起来挺高端的,其实很简单。 
即然是传播,那么至少有两个东西,才可以发生传播。单体不存在传播这个行为。

事务传播行为(propagation behavior)指的就是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行。 
例如:methodA事务方法调用methodB事务方法时,methodB是继续在调用者methodA的事务中运行呢,还是为自己开启一个新事务运行,这就是由methodB的事务传播行为决定的。

Spring定义了七种传播行为:

现在来看看传播行为

1、PROPAGATION_REQUIRED

如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务。 
可以把事务想像成一个胶囊,在这个场景下方法B用的是方法A产生的胶囊(事务)。 

举例有两个方法:

  1. @Transactional(propagation = Propagation.REQUIRED)

  2.  

    public void methodA() {

  3.  

    methodB();

  4.  

    // do something

  5.  

    }

  6.  

  7.  

    @Transactional(propagation = Propagation.REQUIRED)

  8.  

    public void methodB() {

  9.  

    // do something

  10.  

    }

单独调用methodB方法时,因为当前上下文不存在事务,所以会开启一个新的事务。 
调用methodA方法时,因为当前上下文不存在事务,所以会开启一个新的事务。当执行到methodB时,methodB发现当前上下文有事务,因此就加入到当前事务中来。

2、PROPAGATION_SUPPORTS

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

  1. @Transactional(propagation = Propagation.REQUIRED)

  2.  

    public void methodA() {

  3.  

    methodB();

  4.  

    // do something

  5.  

    }

  6.  

  7.  

    // 事务属性为SUPPORTS

  8.  

    @Transactional(propagation = Propagation.SUPPORTS)

  9.  

    public void methodB() {

  10.  

    // do something

  11.  

    }

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

3、PROPAGATION_MANDATORY

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

  1. @Transactional(propagation = Propagation.REQUIRED)

  2.  

    public void methodA() {

  3.  

    methodB();

  4.  

    // do something

  5.  

    }

  6.  

  7.  

    // 事务属性为MANDATORY

  8.  

    @Transactional(propagation = Propagation.MANDATORY)

  9.  

    public void methodB() {

  10.  

    // do something

  11.  

    }

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

4、PROPAGATION_REQUIRES_NEW

使用PROPAGATION_REQUIRES_NEW,需要使用 JtaTransactionManager作为事务管理器。 
它会开启一个新的事务。如果一个事务已经存在,则先将这个存在的事务挂起。

  1. @Transactional(propagation = Propagation.REQUIRED)

  2.  

    public void methodA() {

  3.  

    doSomeThingA();

  4.  

    methodB();

  5.  

    doSomeThingB();

  6.  

    // do something else

  7.  

    }

  8.  

  9.  

  10.  

    // 事务属性为REQUIRES_NEW

  11.  

    @Transactional(propagation = Propagation.REQUIRES_NEW)

  12.  

    public void methodB() {

  13.  

    // do something

  14.  

    }

当调用

  1. main{

  2.  

    methodA();

  3.  

    }

相当于调用

  1. main(){

  2.  

    TransactionManager tm = null;

  3.  

    try{

  4.  

    //获得一个JTA事务管理器

  5.  

    tm = getTransactionManager();

  6.  

    tm.begin();//开启一个新的事务

  7.  

    Transaction ts1 = tm.getTransaction();

  8.  

    doSomeThing();

  9.  

    tm.suspend();//挂起当前事务

  10.  

    try{

  11.  

    tm.begin();//重新开启第二个事务

  12.  

    Transaction ts2 = tm.getTransaction();

  13.  

    methodB();

  14.  

    ts2.commit();//提交第二个事务

  15.  

    } Catch(RunTimeException ex) {

  16.  

    ts2.rollback();//回滚第二个事务

  17.  

    } finally {

  18.  

    //释放资源

  19.  

    }

  20.  

    //methodB执行完后,恢复第一个事务

  21.  

    tm.resume(ts1);

  22.  

    doSomeThingB();

  23.  

    ts1.commit();//提交第一个事务

  24.  

    } catch(RunTimeException ex) {

  25.  

    ts1.rollback();//回滚第一个事务

  26.  

    } finally {

  27.  

    //释放资源

  28.  

    }

  29.  

    }

在这里,我把ts1称为外层事务,ts2称为内层事务。从上面的代码可以看出,ts2与ts1是两个独立的事务,互不相干。Ts2是否成功并不依赖于 ts1。如果methodA方法在调用methodB方法后的doSomeThingB方法失败了,而methodB方法所做的结果依然被提交。而除了 methodB之外的其它代码导致的结果却被回滚了

5、PROPAGATION_NOT_SUPPORTED

PROPAGATION_NOT_SUPPORTED 总是非事务地执行,并挂起任何存在的事务。使用PROPAGATION_NOT_SUPPORTED,也需要使用JtaTransactionManager作为事务管理器。 

6、PROPAGATION_NEVER

总是非事务地执行,如果存在一个活动事务,则抛出异常。

7、PROPAGATION_NESTED

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

这里关键是嵌套执行。

  1. @Transactional(propagation = Propagation.REQUIRED)

  2.  

    methodA(){

  3.  

    doSomeThingA();

  4.  

    methodB();

  5.  

    doSomeThingB();

  6.  

    }

  7.  

  8.  

    @Transactional(propagation = Propagation.NEWSTED)

  9.  

    methodB(){

  10.  

    ……

  11.  

    }

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

  1. main(){

  2.  

    Connection con = null;

  3.  

    Savepoint savepoint = null;

  4.  

    try{

  5.  

    con = getConnection();

  6.  

    con.setAutoCommit(false);

  7.  

    doSomeThingA();

  8.  

    savepoint = con2.setSavepoint();

  9.  

    try{

  10.  

    methodB();

  11.  

    } catch(RuntimeException ex) {

  12.  

    con.rollback(savepoint);

  13.  

    } finally {

  14.  

    //释放资源

  15.  

    }

  16.  

    doSomeThingB();

  17.  

    con.commit();

  18.  

    } catch(RuntimeException ex) {

  19.  

    con.rollback();

  20.  

    } finally {

  21.  

    //释放资源

  22.  

    }

  23.  

    }

当methodB方法调用之前,调用setSavepoint方法,保存当前的状态到savepoint。如果methodB方法调用失败,则恢复到之前保存的状态。但是需要注意的是,这时的事务并没有进行提交,如果后续的代码(doSomeThingB()方法)调用失败,则回滚包括methodB方法的所有操作。嵌套事务一个非常重要的概念就是内层事务依赖于外层事务。外层事务失败时,会回滚内层事务所做的动作。而内层事务操作失败并不会引起外层事务的回滚。

PROPAGATION_NESTED 与PROPAGATION_REQUIRES_NEW的区别:

它们非常类似,都像一个嵌套事务,如果不存在一个活动的事务,都会开启一个新的事务。 
使用 PROPAGATION_REQUIRES_NEW时,内层事务与外层事务就像两个独立的事务一样,一旦内层事务进行了提交后,外层事务不能对其进行回滚。两个事务互不影响。两个事务不是一个真正的嵌套事务。同时它需要JTA事务管理器的支持。

使用PROPAGATION_NESTED时,外层事务的回滚可以引起内层事务的回滚。而内层事务的异常并不会导致外层事务的回滚,它是一个真正的嵌套事务。DataSourceTransactionManager使用savepoint支持PROPAGATION_NESTED时,需要JDBC 3.0以上驱动及1.4以上的JDK版本支持。其它的JTATrasactionManager实现可能有不同的支持方式。

PROPAGATION_REQUIRES_NEW 启动一个新的, 不依赖于环境的 “内部” 事务. 这个事务将被完全 commited 或 rolled back 而不依赖于外部事务, 它拥有自己的隔离范围, 自己的锁, 等等. 当内部事务开始执行时, 外部事务将被挂起, 内务事务结束时, 外部事务将继续执行。

另一方面, PROPAGATION_NESTED 开始一个 “嵌套的” 事务, 它是已经存在事务的一个真正的子事务. 潜套事务开始执行时, 它将取得一个 savepoint. 如果这个嵌套事务失败, 我们将回滚到此 savepoint. 潜套事务是外部事务的一部分, 只有外部事务结束后它才会被提交。

由此可见, PROPAGATION_REQUIRES_NEW 和 PROPAGATION_NESTED 的最大区别在于, PROPAGATION_REQUIRES_NEW 完全是一个新的事务, 而 PROPAGATION_NESTED 则是外部事务的子事务, 如果外部事务 commit, 嵌套事务也会被 commit, 这个规则同样适用于 roll back.

原文地址:https://www.cnblogs.com/YuyuanNo1/p/11400638.html

时间: 2024-11-04 03:30:44

spring事务的7种传播行为的相关文章

spring事务的7种传播级别

PROPAGATION_REQUIRED ,默认的spring事务传播级别,使用该级别的特点是,如果上下文中已经存在事务,那么就加入到事务中执行,如果当前上下文中不存在事务,则新建事务执行.所以这个级别通常能满足处理大多数的业务场景. PROPAGATION_SUPPORTS,从字面意思就知道,supports,支持,该传播级别的特点是,如果上下文存在事务,则支持事务加入事务,如果没有事务,则使用非事务的方式执行.所以说,并非所有的包在transactionTemplate.execute中的代

实现spring事务的四种方式

用一个银行账号转钱的案例来说明spring事务的实现.在转钱过程中,一个账号钱增加,另一个减少,那么当有异常产生时,就会出现钱转丢了的现象一个减少了,而另一个没有增加,这个时候就需要把这两个行为绑定到一起,要么同时发生,要么都不发生这就用到了事务,事务就是指在逻辑上的一组操作,这组操作要么全部成功,要么全部失败 实现spring事务的四种方式分别为:(1)编程式事务管理:需要手动编写代码,在实际开发中很少使用(2)声明式事务管理:(2.1)基于TransactionProxyFactoryBea

Spring事务的5种隔离级别和7种传播性

隔离级别 isolation,5 种: ISOLATION_DEFAULT,ISOLATION_READ_UNCOMMITTED,ISOLATION_READ_COMMITTED,ISOLATION_REPEATABLE_READ,ISOLATION_SERIALIZABLE, 隔离级别解决的问题: 脏读, 幻读, 不可重复读, 传播性 propagation,7 种: PROPAGATION_REQUIRED,PROPAGATION_SUPPORTS,PROPAGATION_MANDATORY

Spring事务隔离级别和传播特性

在Spring中,声明式事务是用事务参数来定义的.一个事务参数就是对事务策略应该如何应用到某个方法的一段描述,如下图所示一个事务参数共有5个方面组成: 传播行为 事务的第一个方面是传播行为.传播行为定义关于客户端和被调用方法的事务边界.Spring定义了7中传播行为. 传播行为 意义 PROPAGATION_MANDATORY 表示该方法必须运行在一个事务中.如果当前没有事务正在发生,将抛出一个异常 PROPAGATION_NESTED 表示如果当前正有一个事务在进行中,则该方法应当运行在一个嵌

Spring事务隔离级别与传播机制,spring+mybatis+atomikos实现分布式事务管理

本文转载于本人另一博客[http://blog.csdn.net/liaohaojian/article/details/68488150] 1.事务的定义:事务是指多个操作单元组成的合集,多个单元操作是整体不可分割的,要么都操作不成功,要么都成功.其必须遵循四个原则(ACID). 原子性(Atomicity):即事务是不可分割的最小工作单元,事务内的操作要么全做,要么全不做: 一致性(Consistency):在事务执行前数据库的数据处于正确的状态,而事务执行完成后数据库的数据还是应该处于正确

spring 事务的两种用法

spring事务两种使用方法 [email protected] 注解 2.AOP 配置 xml (需要依赖包:aopalliance-1.0.jar/ aspectjweaver-1.8.8.jar / spring-aspects-4.2.5.RELEASE.jar) 重要说明: spring-aspects-4.2.5.jar 与 aspectjweaver-1.8.8.jar 是版本匹配的.如果版本不正确会报错误: java.lang.IllegalStateException: Exp

spring事务隔离级别、传播行为以及spring+mybatis+atomikos实现分布式事务管理

转载自:http://blog.csdn.net/liaohaojian/article/details/68488150 1.事务的定义:事务是指多个操作单元组成的合集,多个单元操作是整体不可分割的,要么都操作不成功,要么都成功.其必须遵循四个原则(ACID). 原子性(Atomicity):即事务是不可分割的最小工作单元,事务内的操作要么全做,要么全不做: 一致性(Consistency):在事务执行前数据库的数据处于正确的状态,而事务执行完成后数据库的数据还是应该处于正确的状态,即数据完整

(转)spring事务管理几种方式

转自:http://blog.csdn.net/jeamking/article/details/43982435 前段时间对Spring的事务配置做了比较深入的研究,在此之间对Spring的事务配置虽说也配置过,但是一直没有一个清楚的认识.通过这次的学习发觉Spring的事务配置只要把思路理清,还是比较好掌握的. 总结如下: Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource.TransactionManager和代理机制这三部分,无论哪种配置方式,一般变化的只是

[转] spring事务管理几种方式

前段时间对Spring的事务配置做了比较深入的研究,在此之间对Spring的事务配置虽说也配置过,但是一直没有一个清楚的认识.通过这次的学习发觉Spring的事务配置只要把思路理清,还是比较好掌握的. 总结如下: Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource.TransactionManager和代理机制这三部分,无论哪种配置方式,一般变化的只是代理机制这部分. DataSource.TransactionManager这两部分只是会根据数据访问方式有所变化,