Spring事务的传播行为

80

事务的传播特性

事务的传播特性就是当一个事务方法被另一个事务方法调用的时候,这个事务方法应该如何执行。

以 Java 为例,Java 的 Spring 框架中,使用注解的方式来使用事务非常简洁方便:

@Service
public class PersonServive {
    @Transactional(propagation = Propagation.REQUIRED)
    public void methodA() {
        System.out.println("run method a.");
        methodB();
    }
  
    @Transactional(prapagation = Propagation.REQUIRES_NEW)
    public void methodB() {
        System.out.println("run method b.");
    }
}

例子当中,方法 A 调用方法 B,两个方法都用注解显式的标识了开启的事务模式,其中方法 A 开启的是 PROPAGATION_REQUIRED ,方法 B 开启的是 PROPAGATION_REQUIRES_NEW ,这种传播机制下,就是方法 B 有自己的事务,出错就回滚,没出错就提交,对方法 A 是不会产生影响的,无论是方法 A 最后是回滚还是提交,对于方法 B 事务的执行,不会产生影响。两个事务都是互不影响。

Spring 中的七种事务传播机制

1. 不需要事务

PROPAGATION_NEVER : 没有就非事务执行,有就抛异常。

PROPAGATION_NOT_SUPPORTED : 没有就非事务执行,有就直接挂起,然后非事务执行

2. 可以有事务,也可以没有事务

PROPAGATION_SUPPORTS : 调用者有事务就加入,一起在事务中执行,没有就非事务执行。

3. 一定需要事务

PROPAGATION_REQUIRES_NEW : 有没有都新建事务,如果调用者有事务,就挂起调用者已经开启的。自己新建事务。

PROPAGATION_REQUIRED : 如果没有,就新建一个事务,如果有,就加入当前事务,一起在事务中运行。Spring 默认是这种类型。

PROPAGATION_NESTED : 如果没有事务,就新建一个事务,如果原来有,就在当前事务中嵌套其他事务。

PROPAGATOIN_MANDATORY : 如果没有事务就报错,如果有事务,就参与当前事务,一起在事务中执行。

需要注意的是对于 PROPAGATION_NESTED ,里层事务的回滚,不会影响外层事务。但是,如果外层事务出异常回滚,里层的事务也会回滚,比如前面例子当中的方法 A 和方法 B,如果方法 A 回滚,方法 B 即使成功不报错可以提交,也会回滚。