当前位置:   article > 正文

Spring事务的传播机制_propagation = propagation.not_supported

propagation = propagation.not_supported

事务的传播机制:

  • @Transactional(propagation=Propagation.REQUIRED)

如果有事务,那么加入事务,没有的话新建一个(默认情况下)

  • @Transactional(propagation=Propagation.NOT_SUPPORTED)

容器不为这个方法开启事务

  • @Transactional(propagation=Propagation.REQUIRES_NEW)

不管是否存在事务,都创建一个新的事务,原来的挂起,新的执行完毕,继续执行老的事务

  • @Transactional(propagation=Propagation.MANDATORY)

必须在一个已有的事务中执行,否则抛出异常

  • @Transactional(propagation=Propagation.NEVER)

必须在一个没有的事务中执行,否则抛出异常(与Propagation.MANDATORY相反)

  • @Transactional(propagation=Propagation.SUPPORTS)

如果其他bean调用这个方法,在其他bean中声明事务,那就用事务。如果其他bean没有声明事务,那就不用事务。

@Transactional(propagation=Propagation.NESTED)

如果当前存在事务,则在嵌套事务内执行,类似数据库事务保存点。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。

案例代码

PROPAGATION_REQUIRED

  1. ServiceA {
  2. @Transactional(propagation = Propagation.REQUIRED)
  3. void methodA() {
  4. ServiceB.methodB();
  5. }
  6. }
  7. ServiceB {
  8. @Transactional(propagation = Propagation.REQUIRED)
  9. void methodB() {
  10. }
  11. }

ServiceA.methodA 与 ServiceB.methodB 同时成功,否则都失败。 

PROPAGATION_SUPPORTS

  1. ServiceA {
  2. @Transactional(propagation = Propagation.REQUIRED)
  3. void methodA() {
  4. ServiceB.methodB();
  5. }
  6. }
  7. ServiceB {
  8. @Transactional(propagation = Propagation.SUPPORTS)
  9. void methodB() {//依赖调用方法是否事务
  10. }
  11. }

假设当前在事务中,即以事务的形式执行。假设当前不在一个事务中,那么就以非事务的形式执行

PROPAGATION_MANDATORY

  1. ServiceA {
  2. @Transactional(propagation = Propagation.REQUIRED)
  3. void methodA() {
  4. ServiceB.methodB();
  5. }
  6. }
  7. ServiceB {
  8. @Transactional(propagation = Propagation.MANDATORY)
  9. void methodB() {//必须事务执行
  10. }
  11. }

必须在一个事务中执行。也就是说,他仅仅能被一个父事务调用。否则,他就要抛出异常。ServiceA.methodA()必须以事务执行。

PROPAGATION_REQUIRES_NEW

  1. ServiceA {
  2. @Transactional(propagation = Propagation.REQUIRED)
  3. void methodA() {//事务A
  4. ServiceB.methodB();
  5. }
  6. }
  7. ServiceB {
  8. @Transactional(propagation = Propagation.REQUIRES_NEW)
  9. void methodB() {//事务B
  10. }
  11. }

ServiceA.methodA 与ServiceB.methodB是2个独立的事务,互不影响。

当运行到ServiceB.methodB的时候,ServiceA.methodA所在的事务就会挂起。ServiceB.methodB会起一个新的事务。等待ServiceB.methodB的事务完毕以后,它才继续运行。

与REQUIRED 的事务差别在于事务的回滚程度。由于ServiceB.methodB是新起一个事务,那么就是存在两个不同的事务。假设ServiceB.methodB已经提交,那么ServiceA.methodA失败回滚。ServiceB.methodB是不会回滚的。假设ServiceB.methodB失败回滚,假设他抛出的异常被ServiceA.methodA捕获,ServiceA.methodA事务仍然可能提交。

PROPAGATION_NOT_SUPPORTED

  1. ServiceA {
  2. @Transactional(propagation = Propagation.REQUIRED)
  3. void methodA() {
  4. ServiceB.methodB();
  5. }
  6. }
  7. ServiceB {
  8. @Transactional(propagation = Propagation.NOT_SUPPORTED)
  9. void methodB() {//非事务方式执行
  10. }
  11. }

当前不支持事务。比方ServiceA.methodA的事务级别是PROPAGATION_REQUIRED 。而ServiceB.methodB的事务级别是PROPAGATION_NOT_SUPPORTED ,那么当执行到ServiceB.methodB时,ServiceA.methodA的事务挂起;而它以非事务的状态执行完,再继续ServiceA.methodA的事务。

PROPAGATION_NEVER

  1. ServiceA {
  2. @Transactional(propagation = Propagation.REQUIRED)
  3. void methodA() {
  4. ServiceB.methodB();
  5. }
  6. }
  7. ServiceB {
  8. @Transactional(propagation = Propagation.NEVER)
  9. void methodB() {// 抛出异常
  10. }
  11. }

不能在事务中执行。如果ServiceA.methodA的事务级别是PROPAGATION_REQUIRED。 而ServiceB.methodB的事务级别是PROPAGATION_NEVER ,那么ServiceB.methodB就要抛出异常了。

PROPAGATION_NESTED

如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。

当使用PROPAGATION_NESTED时,底层的数据源必须基于JDBC 3.0,并且实现者需要支持保存点事务机制。

嵌套事务不能够提交,它必须通过外层事务来完成提交的动作,外层事务的回滚也会造成内部事务的回滚。

PROPAGATION_NESTED 将创建一个依赖于外层事务的子事务,当外层事务提交或回滚时,子事务也会连带提交和回滚。

事务的原理

数据库事务XA模型

  • Transaction Coordinator (TC): 事务协调器,维护全局事务的运行状态,负责协调并驱动全局事务的提交或回滚。
  • Transaction Manager (TM): 控制全局事务的边界,负责开启一个全局事务,并最终发起全局提交全局回滚的决议。
  • Resource Manager (RM): 控制分支事务,负责分支注册、状态汇报,并接收事务协调器的指令,驱动分支(本地)事务的提交和回滚。

事务传播行为就是事务协调器对分支事务的一种控制。

配置方式

  1. <tx:advice id="txAdvice" transaction-manager="txManager">
  2. <tx:attributes>
  3. <!--设置所有匹配的方法,然后设置传播级别和事务隔离-->
  4. <tx:method name="save*" propagation="REQUIRED" />
  5. <tx:method name="add*" propagation="REQUIRED" />
  6. <tx:method name="create*" propagation="REQUIRED" />
  7. <tx:method name="insert*" propagation="REQUIRED" />
  8. <tx:method name="update*" propagation="REQUIRED" />
  9. <tx:method name="merge*" propagation="REQUIRED" />
  10. <tx:method name="del*" propagation="REQUIRED" />
  11. <tx:method name="remove*" propagation="REQUIRED" />
  12. <tx:method name="put*" propagation="REQUIRED" />
  13. <tx:method name="get*" propagation="SUPPORTS" read-only="true" />
  14. <tx:method name="count*" propagation="SUPPORTS" read-only="true" />
  15. <tx:method name="find*" propagation="SUPPORTS" read-only="true" />
  16. <tx:method name="list*" propagation="SUPPORTS" read-only="true" />
  17. <tx:method name="*" propagation="SUPPORTS" read-only="true" />
  18. </tx:attributes>
  19. </tx:advice>
  20. <!--开启注解的方式-->
  21. <tx:annotation-driven transaction-manager="transactioManager" />

参考:Seata实战-分布式事务简介及demo上手

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/405430
推荐阅读
相关标签
  

闽ICP备14008679号