事务的传播机制

Posted wei-cy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了事务的传播机制相关的知识,希望对你有一定的参考价值。

事务的传播机制有7种,下面的传播机制都是针对于被调用的方法来说的,理解起来需要想象成两个service,本文的案例主要讲的是传播机制中的PROPAGATION_REQUIRES_NEW和PROPAGATION_NESTED。

(1)PROPAGATION_REQUIRED(默认):支持使用当前事务,如果当前事务不存在,创建一个新事务。

(2)PROPAGATION_SUPPORTS:支持使用当前事务,如果当前事务不存在,则不使用事务。

(3)PROPAGATION_MANDATORY:中文翻译为强制,支持使用当前事务,如果当前事务不存在,则抛出Exception。

(4)PROPAGATION_REQUIRES_NEW(常用):创建一个新事务,如果当前事务存在,把当前事务挂起。

这个方法会独立提交事务,不受调用者的事务影响,父级异常,它也是正常提交。

(5)PROPAGATION_NOT_SUPPORTED:无事务执行,如果当前事务存在,把当前事务挂起。

(6)PROPAGATION_NEVER:无事务执行,如果当前有事务则抛出Exception。

(7)PROPAGATION_NESTED(常用):嵌套事务,如果当前事务存在,那么在嵌套的事务中执行。如果当前事务不存在,则表现跟REQUIRED一样。

如果当前存在事务,它将会成为父级事务的一个子事务,方法结束后并没有提交,只有等父事务结束才提交。

如果当前没有事务,则新建事务。

如果它异常,父级可以捕获它的异常而不进行回滚,正常提交。

但如果父级异常,它必然回滚,这就是和 REQUIRES_NEW 的区别。

 

下面直接上案例:

A、B都开启了事务,并且事务A里面方法调用了事务B里的方法

 技术图片

 

技术图片

 

 在这里让B发生异常,那么最后经过测试A、B都会发生异常,并且回滚(如果A里面对B进行了try-catch,那么还是会都会回滚)

那么怎样实现B发生异常后,回滚了。A不回滚,数据insert成功?(bz在业务需求中遇到过这样的)

 

解决方法:(1)事务B里面修改传播机制(默认的机制是PROPAGATION_REQUIRED),经过测试以下两种机制都是可以的。

技术图片

 

 技术图片

 

 

Propagation_requires_new和propagation_nested的区别(重要,比较常用):

前者如果父级发生了异常,则子事务也是正常提交;后者是如何父级发生了异常,则子事务必然发生回滚。

具体使用哪种传播机制,当然还得根据实际的业务场景来决定。

 

以上是关于事务的传播机制的主要内容,如果未能解决你的问题,请参考以下文章

Spring事务传播机制详解

Spring事务传播机制详解

面试突击87:说一下 Spring 事务传播机制?

事务的传播机制

事务的传播机制

Spring事务之传播机制