Spring的事务传播机制

参考文章:https://segmentfault.com/a/1190000013341344

什么是事务传播机制

在这里插入图片描述
官方的解释:在一个事务的范围内的操作将会成为事务的一部分并且在这个事务中执行。但是,如果已经存在一个事务的环境,也可以改变一个在该环境中带有事务属性方法的行为。比如:这个带事务属性的方法可以在已经存在的事务中执行操作,它也可以再新开启一个事务在这个新开启的事务中执行操作。

我个人的理解:Propagation定义了一个带有事务属性的里层方法在被另一个带有事务属性的外层方法调用时,里层方法将以什么样的形式去执行操作。

比如下面的代码块中:methodA和methodB都开启了事务,methodA中调用了methodB。是应该把methodA和methodB看成同一个事务进行操作(methodA与methodB会互相影响)?还是methodA和methodB各自使用了不同的事务,二者互不影响?这就与@Transactional中的传播机制Propagation属性相关了。

@Transactional
methodA(){
	...操作...
	@Transactional
	methodB();
}

Propagation可以取的值:
Propagation

测试准备

主要使用的方法:

  1. 里层方法异常,自己捕获处理(try catch),不被外层方法感知;
  2. 里层方法异常委托给外层方法来处理;
  3. 外层方法异常。

测试Propagation

REQUIRED

REQUIRED为Propagation属性默认的值

  1. 外层方法不开启事务,两个里层方法开启事务并设置传播机制为REQUIRED,其中一个方法会抛出异常:无异常的执行成功,有异常的回滚

  2. 外层方法开启事务,两个里层方法开启事务并设置传播机制为REQUIRED,其中一个方法会抛出异常:两个里层方法的事务均回滚

  3. 外层方法开启事务,两个里层方法开启事务并设置传播机制为REQUIRED,其中一个方法会抛出异常但是这个方法自己使用try catch捕获了这个异常:两个里层方法的事务均回滚。

  4. 外层方法开启事务,里层方法开启事务并设置传播机制为REQUIRED,外层方法抛出异常:里层方法回滚

总结:如果外层未开启,里层方法的事务互不干扰;外层开启了事务,里层外层使用同一个事务

REQUIRED_NEW
  1. 外层方法不开启事务,两个里层方法开启事务并设置传播机制为REQUIRED_NEW,其中一个方法会抛出异常:无异常的执行成功,有异常的回滚

  2. 外层方法开启事务,两个里层方法开启事务并设置传播机制为REQUIRED_NEW,其中一个方法会抛出异常:无异常的执行成功,有异常的回滚

  3. 外层方法开启事务,一个里层方法开启事务并设置传播机制为REQUIRED,另一个设置为REQUIRED_NEW, 外层方法抛出异常:传播机制为REQUIRED的里层方法回滚,另一个REQUIRED_NEW的正常执行

总结:无论外层方法开不开启事务,里层方法都会自己创建一个新的事务去执行与其他的事务(外层,其他里层的事务)互不干扰

NESTED
  1. 外层方法不开启事务,两个里层方法开启事务并设置传播机制为NESTED,其中一个方法会抛出异常:无异常的执行成功,有异常的回滚

  2. 外层方法开启事务,两个里层方法开启事务并设置传播机制为NESTED,其中一个方法会抛出异常:两个里层方法的事务均回滚

  3. 外层方法开启事务,两个里层方法开启事务并设置传播机制为NESTED,其中一个方法会抛出异常但是这个方法自己使用try catch捕获了这个异常:未抛出异常的执行成功,抛出异常的回滚

  4. 外层方法开启事务,里层方法开启事务并设置传播机制为NESTED,外层方法抛出异常:里层方法回滚

总结:如果外层开启了事务,里层外层使用同一个事务,外层事务回滚子事务也会滚,子事务的异常未被外层事务感知则外层事务不会回滚;
外层未开启事务,子事务间互不影响

我总结的不够好,可以看看这个博主的,我把截图放在下面了
https://segmentfault.com/a/1190000013341344
在这里插入图片描述

MANDATORY
  1. 外层方法不开启事务,里层方法开启事务并设置传播机制为MANDATORY:结果抛出异常
    org.springframework.transaction.IllegalTransactionStateException: No existing transaction found for transaction marked with propagation ‘mandatory’
  2. 外层方法开启事务,里层方法开启事务并设置传播机制为MANDATORY:插入成功
  3. 外层方法开启事务,两个里层方法开启事务并设置传播机制为MANDATORY,其中一个里层方法抛出异常:两个里层方法的事务均回滚
  4. 外层方法开启事务,两个里层方法开启事务并设置传播机制为MANDATORY,其中一个里层方法抛出异常并自己try catch 捕获:两个里层方法的事务均回滚

总结:外层方法必须开启事务,否则抛出IllegalTransactionStateException异常。外层方法和里层方法使用同一个事务

SUPPORTS
  1. 外层方法不开启事务,两个里层方法开启事务并设置传播机制为SUPPORTS,其中一个方法会抛出异常:两个方法互不影响,抛出异常的方法没有影响到另一个方法

  2. 外层方法开启事务,两个里层方法开启事务并设置传播机制为SUPPORTS,其中一个方法会抛出异常:正常的方法也回滚了

  3. 外层方法开启事务,两个里层方法开启事务并设置传播机制为SUPPORTS,其中一个方法会抛出异常但是这个方法自己使用try catch捕获了这个异常:正常的方法也回滚了
    org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only

总结:如果外层方法开启事务,外层方法和里层方法使用同一个事务;
如果未开启,均以非事务的形式执行

NOT_SUPPORTED
  1. 外层方法开启事务,里层方法开启事务并设置传播机制为NOT_SUPPORTED,外层方法抛出异常:里层方法正常执行,里层方法和外层方法互不干扰
  2. 外层方法开启事务,两个里层方法开启事务并设置传播机制为NOT_SUPPORTED,其中一个方法会抛出异常:两个里层方法均可执行,出现异常的方法也未回滚

总结:以非事务的形式执行,外层开启了事务则挂起不抛出异常

NEVER
  1. 外层方法不开启事务,两个里层方法开启事务并设置传播机制为NEVER,并且其中一个里层方法抛出异常:两个里层执行成功,出现异常的里层方法并未回滚

  2. 外层方法开启事务,里层方法开启事务并设置传播机制为NEVER:里层方法未执行抛出异常
    org.springframework.transaction.IllegalTransactionStateException: Existing transaction found for transaction marked with propagation ‘never’

总结:里层方法以非事务的形式执行,外层方法必须开不启事务,否则抛出IllegalTransactionStateException异常

总结

外层不开启事务,里层事务互不干扰;
不使用事务会抛出异常的:NEVER;
使用事务会抛出异常的: MANDATORY;
使用事务不会抛出异常的:NOT_SUPPORT;
可以使用事务也可以不使用事务的:SUPPORT(但是外层开启事务里层如果出现异常并自己捕获,所有里层方法均回滚并会抛出异常);
外层里层使用同一个事务,不管哪里出现异常都会回滚的:REQUIRED;
外层里层使用同一个事务,外层异常里层一起回滚,里层异常并且如果不被外层感知,外层不会回滚的:NESTED;
外层里层使用不同事务:REQUIRED_NEW。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值