Spring 的事务传播类型

Spring 的事务传播类型_第1张图片
Java知己

Spring 的事务传播机制类型定义在了 Propagation 枚举类中。主要有以下几种类型。

public enum Propagation {
REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED),
SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS),
MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY),
REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW),
NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED),
NEVER(TransactionDefinition.PROPAGATION_NEVER),
NESTED(TransactionDefinition.PROPAGATION_NESTED);
// ...
}

下面主要对常用的 PROPAGATION_REQUIRED、PROPAGATION_REQUIRES_NEW 和 PROPAGATION_NESTED 做详细介绍。

PROPAGATION_REQUIRED

PROPAGATION_REQUIRED 表示加入当前正要执行的事务不在另外一个事务中,那么就开启一个新的事务。

例如,ServiceB.methodB() 的事务级别定义为 PROPAGATION_REQUIRED, 那么由于执行 ServiceA.methodA() 时,ServiceA.methodA() 已经开启了事务,这时调用 ServiceB.methodB(),ServiceB.methodB() 看到自己已经运行在 ServiceA.methodA() 的事务内部,就不再开启新的事务。而假如 ServiceA.methodA() 运行时发现自己没有在事务中,它就会为自己分配一个事务。

公众号:「Java知己」,发送「Java测评」,评估你的Java等级。还不赶紧来试一试,测测你到底属于哪个段位哒!!!

这样,在 ServiceA.methodA() 或在 ServiceB.methodB() 内的任何地方出现异常,事务都会被回滚。 即使 ServiceB.methodB() 的事务已经被提交,但是 ServiceA.methodA() 在下面异常了要回滚,那么 ServiceB.methodB() 也会回滚。

图 1 所示为 PROPAGATION_REQUIRED 类型的事务处理流程。

Spring 的事务传播类型_第2张图片
image

PROPAGATION_REQUIRES_NEW

例如,定义 ServiceA.methodA() 的事务级别为 PROPAGATION_REQUIRED,ServiceB.methodB() 的事务级别为 PROPAGATION_REQUIRES_NEW,那么当执行到 ServiceB.methodB() 的时候,ServiceA.methodA() 所在的事务就会挂起,ServiceB.methodB() 会开启一个新的事务。等 ServiceB.methodB 的事务完成以后,ServiceA.methodA() 才继续执行。它与 PROPAGATION_REQUIRED 的事务区别在于,事务的回滚程度。因为 ServiceB.methodB() 是新开启一个事务,那么就 是存在两个不同的事务。如果 ServiceB.methodB() 已经提交,那么 ServiceA.methodA() 失败回滚,ServiceB.methodB() 是不会回滚的。如果 ServiceB.methodB() 失败回滚,如果它抛出的异常被 ServiceA.methodA() 捕获,ServiceA.methodA() 事务仍然可能提交。

图 2 所示为 PROPAGATION_REQUIRES_NEW 类型的事务处理流程。

Spring 的事务传播类型_第3张图片
image

PROPAGATION_NESTED

PROPAGATION_NESTED 使用具有可回滚到的多个保存点的单个物理事务。PROPAGATION_NESTED 与 PROPAGATION_REQUIRES_NEW 的区别是,PROPAGATION_REQUIRES_NEW 另开启一个事务,将会与它的父事务相互独立,而 PROPAGATION_NESTED 的事务和它的父事务是相依的,它的提交要和它的父事务一起。也就是说,如果父事务最后回滚,它也要回滚。如果子事务回滚或提交,不会导致父事务回滚或提交,但父事务回滚将导致子事务回滚。

图 3 所示为 PROPAGATION_NESTED 类型的事务处理流程。

Spring 的事务传播类型_第4张图片
image

关注公众号:「Java知己」,发送「1024」,免费领取 30 本经典编程书籍。​与 10 万程序员一起进步。每天更新Java知识哦,期待你的到来!

Spring 的事务传播类型_第5张图片
Java知己
Spring 的事务传播类型_第6张图片
每日福利

你可能感兴趣的:(Spring 的事务传播类型)