• Spring源码深度解析(六):Spring事务传播机制详解


    前言

    上篇文章我们说过,Spring对事务的控制,是使用AOP切面实现的,我们使用时只需在方法上加上@Transactional注解,这时就有问题了。
    1、A方法调用了B方法,两个方法都有事务,此时如果B方法异常,那么是让B方法提交,还是两个一起回滚。
    2、A方法调用了B方法,但是只有A加了事务,此时是否将B也加入A的事务,如果B异常,是否回滚A。
    3、A方法调用了B方法,两个方法都有事务,B正常执行完,但是A异常,此时是否回滚B的数据。

    正文

    Spring中定义的7种传播类型被定义成了枚举,在枚举类Propagation中定义。使用方式是指定注解的属性。

    @Transactional(propagation=Propagation.REQUIRED)
    
    • 1

    1、REQUIRED

    默认的事务传播级别,使用该级别的特点是,如果上下文中已经存在了事务,那么就加入到当前事务中执行,如果当前上下文中不存在事务,则新建事务执行。这个级别通常能满足大多数的业务场景。

    比如:方法A调用方法B,B的事务级别是REQUIRED,由于A已经起了事务,此时调用B看到上下文中已经有了A的事务,就不再起新的事务。而A在执行时发现自己没有在事务中,就会为自己分配一个事务。这样,方法A或者方法B中任何地方出现异常,事务都会回滚,方法A和方法B都要回滚。

    2、SUPPORTS

    该事务级别特点是:如果上下文中存在事务,则加入事务,如果没有事务,则使用非事务的方式执行。使用场景较少。

    3、MANDATORY

    该事务级别特点是:要求上下文中必须存在事务,否则就会抛出异常。使用场景比如:一段代码不能单独被调用执行,但是一旦被调用,就必须有事务包含,否则跑异常。

    4、REQUIRES_NEW

    该传播级别的特点是:每次都会新建一个事务,并且将上下文中的事务挂起,执行完新建的事务后,再将上下文中的事务恢复并执行。

    比如我们设计方法A的事务级别是REQUIRED,方法B的事务级别是REQUIRES_NEW,那么当B执行的时候,A所在的事务就会挂起,B会起一个新的事务,等B完成后,A事务解挂继续执行。那么,A和B分别在2个不同的事务,互不影响,A失败回滚不会影响B提交,B失败回滚不会影响A提交。

    5、NOT_SUPPORTED

    该传播级别不支持事务,特点就是如果上下文中存在事务,则挂起事务,执行当前逻辑,结束后恢复上下文中的事务。

    6、NEVER

    该传播级别要求上下文中不能存在事务,一旦有事务,就会抛出运行时异常。

    7、NESTED

    和REQUIRES_NEW相似,但又有不同。REQUIRES_NEW另起一个事务,是和它的父事务相互独立的。而NESTED的事务则是和它的父事务相关联的,它的提交要等父事务一起提交,如果父事务回滚,它也要回滚。

    总结

    Spring的七种事务传播机制要根据实际场景来指定。

  • 相关阅读:
    为什么使用 Virtual DOM
    【LeetCode】Day169-子数组的最小值之和
    对一段规律的字符串做修改
    Python计算机二级基本操作题和简单应用题
    【java】[maven]每次创建一个maven模块时java compiler版本就是1.6与实际版本不一致(解决本质问题)
    LeetCode每日一题——2562. Find the Array Concatenation Value
    限制容器中的进程
    PCB电路板去耦电容配置原则有哪些?
    【prometheus】监控MySQL并实现可视化
    QWEN technical report
  • 原文地址:https://blog.csdn.net/qq_32166627/article/details/126386604