Spring事务传播行为

Spring事务的七种传播行为

事务传播行为类型 说明
PROPAGATION_REQUIRED 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
PROPAGATION_SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY 使用当前的事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW 新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER 以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。

本篇文档主要以 PROPAGATION_REQUIRED  PROPAGATION_REQUIRES_NEW两个传播行为讲解

PROPAGATION_REQUIRED此传播行为为Spring默认的传播行为

使用到的实体类 Order1 及Order2

public class Order01 {
    private int id;

    private String orderNo;

    //set get 构造函数等省略
}

表结构

order1的Service业务方法

 @Autowired
    private Order1Mapper order1Mapper;


    @Transactional(propagation = Propagation.REQUIRED)
    public void addOrder1() {
        Order01 order01=new Order01();
        order01.setId(1);
        order01.setOrderNo("order010401");
        System.out.println("Order01进入");
        System.out.println(order01);
        order1Mapper.insert(order01);
    }
    @Transactional(propagation = Propagation.REQUIRED)
    public void addOrder1Exception() {
        Order01 order01=new Order01();
        order01.setId(2);
        order01.setOrderNo("order010401");
        order1Mapper.insert(order01);
        throw new RuntimeException();
    }

 

1.测试 PROPAGATION_REQUIRED

测试代码如下

 public void runOrder(){
        order1Service.addOrder1();
        order1Service.addOrder1Exception();
    }

 addOrder1没有出现异常 addOrder1Exception 手动抛出了一个RuntimeException异常

两个方法都由@Transactional注解修饰

此时执行结果为

addOrder1 addOrder1Exception
执行成功 执行失败抛出异常,事务回滚

 按照我们意愿来想 addOrder1与addOrder1Exception 两个方法 要么全部成功,要么全部不成功

所以在runOrder此方法上加上注解@Transactional(propagation = Propagation.REQUIRED)

此时执行结果为

addOrder1 addOrder1Exception
执行失败 执行失败

 由于runOrder的@Transactional(PROPAGATION_REQUIRED)指代

如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。

所以此时addOrder 与addOrderException的事务都统一由runOder的事务去管理

及以前是 a b 两个小事务 各管各的,现在由C这个事务去管理,a b c 中只要一个地方出现异常 该事务就回滚;

2.测试 PROPAGATION_REQUIRES_NEW

修改order1Service的具体实现逻辑

    @Autowired
    private Order1Mapper order1Mapper;

    @Transactional(propagation = Propagation.REQUIRED)
    public void addOrder1REQUIRED() {
        Order01 order01=new Order01();
        order01.setId(1);
        order01.setOrderNo("order010401");
        order1Mapper.insert(order01);
        throw new RuntimeException();
    }
    @Transactional(propagation = Propagation.REQUIRED)
    public void addOrder1ExceptionREQUIRED() {
        Order01 order01=new Order01();
        order01.setId(2);
        order01.setOrderNo("order010401");
        order1Mapper.insert(order01);
    }
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void addOrder01REQUIRES_NEW() {
        Order01 order01=new Order01();
        order01.setId(3);
        order01.setOrderNo("order010401");
        order1Mapper.insert(order01);
    }
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void addOrder01REQUIRES_NEWException() {
        Order01 order01=new Order01();
        order01.setId(4);
        order01.setOrderNo("order010401");
        order1Mapper.insert(order01);
        throw new RuntimeException();
    }

 在原有逻辑的基础上,修改了方法名,增加了两个方法

.addOrder01REQUIRES_NEW

addOrder01REQUIRES_NEWException

新增的两个方法的事务传播行为都为 PROPAGATION_REQUIRES_NEW

寓意挂起当前事务,重启一个事务

此时执行runOrder方法

@Transactional(propagation = Propagation.REQUIRED)
    public void runOrder(){
        order1Service.addOrder01REQUIRES_NEW();
        order1Service.addOrder1REQUIRED();
        order1Service.addOrder1ExceptionREQUIRED();
        order1Service.addOrder01REQUIRES_NEWException();
    }

执行结果如下

addOrder01REQUIRES_NEW 执行成功
addOrder1REQUIRED 执行失败
addOrder1ExceptionREQUIRED 执行失败
addOrder01REQUIRES_NEWException 执行失败

 addOrder1REQUIRED addOrder1ExceptionREQUIRED执行失败原因:

这两个方法的事务都是有runOrder方法的事务去管理 只要这三个方法有一个地方出现异常 这三个地方都会回滚

addOrder01REQUIRES_NEW 执行成功原因:

此方法的传播行为 寓意 重新启动一个事务 该事务与runOrder事务无关,该事务无论成功与否都不会影响runOrder事务的提交或回滚

addOrder01REQUIRES_NEWException执行失败原因:

此方法新建一个事务,该事务与runOrder事务无关,执行失败只回滚当前事务,不会影响runOrder事务的执行,所以他失败回滚了;

3.PROPAGATION_NESTED(事务嵌套)

日后补充....

 

学而不思则罔,思而不学则殆。

你可能感兴趣的:(java)