Spring事务的7种传播机制

什么是传播机制?

所谓传播机制,指的就是 方法A带有事务,去调用方法带有事务B,方法A,b事务设置的事务属性,会对方法A,B的事务产生什么影响。

类中方法互相调用

  1. 方法A(不带事务)调用同类方法B(带事务)
image.png

B事务不会生效,因为A方法不是增强方法,在代理对象中,A调用的是B的原生方法。必须得通过代理对象调用B的增强后的方法才能触发B的事务。

  1. 方法A(带事务)调用方法B

由上可知,同类中调用B方法,B方法上的任务事务属性都不会生效,不管你A的是否设置。但是由于是同类,用的是本身的对象,所以A+B其实是相当于一个整体受A开启的事务影响。

如果B是异类方法,那么B的事务会受到B方法上设置的事务传播属性影响。因为用的是异类注入进来的代理对象,会触发aop.

不同类中方法互相调用

分析这类方法一定要分两部分来进行,首先是A方法对事务的属性,其次是B方法对事务的属性。A方法对B方法的影响只存在于运行A方法时是否已经开启事务。所以就会有7*7 49种情况。

<meta charset="utf-8">

image.png

注意:异常是否捕获对事务的影响。

异常捕获了就不会发生回滚!!! 因为在事务源码中是通过 try{ 增强方法 }catch(Exception e){ 事务回滚。 } 增强方法自己处理的异常就不会被spring,catch到

1、PROPAGATION_REQUIRED

若当前存在事务,则加入该事务,若不存在事务,则新建一个事务。

所谓当前,其实是上下文,比如B在A的事务范围之内。

实例:

  1. A:Propagation.REQUIRED B:Propagation.REQUIRED

执行A时,A发现当前不存在事务,会新建一个事务,B被A调用,发现A已经开启事务了,共处一个上下文。所以就满足当前存在事务的条件,则使用A的事务。

结论:这种情况下,A和B为同一个事务。A和B中任何一个发生异常,都会一起回滚。

  1. A:Propagation.REQUIRED B:Propagation.REQUIRED_NEW

B设置为REQUIRED_NEW,如果存在事务,则挂起当前事务: 这样子A的事务只有当B的事务完成之后,才会继续执行A的事务。B的事务可以说是独立在A事务之中的。所以当A存在异常时,不会影响B的事务.

结论: 当A存在异常,B不存在,只有A回滚。B的事务在A回滚之前已经结束

当A不存在异常,B存在异常时,只有B回滚。B的事务是独立的。

当AB同时存在异常时,A的事务会在B事务完成之后再次进行,所以是B回滚了之后,A再回滚。

3.A:Propagation.REQUIRED B:Propagation.REQUIRED_NESTED

执行A时,A发现当前不存在事务,会新建一个事务,执行B时,发现已有事务,挂起A的事务,会新建一个子事务.和Propagation.REQUIRED_NEW不同的时,这种事务是有savepoint的,如果A存在异常,回滚,B的事务即使已经提交仍然会回滚至savePoint.如果B存在异常,回滚之后,也同样的会影响到A,导致A也跟着混滚。和第一种场景比较相似,但是第一种只存在一个事务,这种是有两个事务,但是会互相影响,效果的话和第一种差不多。

4. Propagation.REQUIRED B:Propagation.REQUIRED_NEVER

执行A时,A发现当前不存在事务,会新建一个事务,执行B时,发现已有事务,会抛异常,并且不会执行业务代码.抛出的异常会导致A也进行回滚。

5. Propagation.REQUIRED B:Propagation.NOT_SUPPORTS

执行A时,A发现当前不存在事务,会新建一个事务,执行B时,发现已有事务,挂起A事务,B是不存在事务的(B出现异常也不回滚)。当B执行完之后,再进行A的事务。

其他的各种情况 跟上面这样分析即可。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容