Spring事务的传播行为
事务的传播特性
事务的传播特性就是当一个事务方法被另一个事务方法调用的时候,这个事务方法应该如何执行。
以 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 即使成功不报错可以提交,也会回滚。