• Spring的7种事务传播机制


    前言

    什么是事务?
    事务就是用户定义的一系列数据库操作,这些操作可以视为一个完成的逻辑处理工作单元,要么全部执行,要么全部不执行,是不可分割的工作单元。对数据库的增删改查操作

    传播机制是什么?
    当A调用B的时候,两个事务是怎么运行的?A出现异常,或者B出现异常,A回不回滚,B回不回滚?还是A回滚,B不回滚?这些问题

    事务 以非事务性方式运行是什么意思?
    非事务的方式运行,其实就是设置为自动提交了,如果一个方法中有多个操作,则每个操作都会在不同事务中完成,不会保证他们的原子性

    事务挂起是什么意思?
    在方法A开始运行时,系统为它建立Transaction(“全赞可凶弄”),方法A中对于数据库的处理操作,会在该Transaction的控制之下。
    这时,方法A调用方法B,方法A打开的 Transaction将挂起,方法B中任何数据库操作,都不在该Transaction的管理之下。
    当方法B返回,方法A继续运行,之前的Transaction回复,后面的数据库操作继续在该Transaction的控制之下 提交或回滚。

    怎么使用?
    在方法上使用@Transactional(事务,“全赞可凶弄”)注解,后面设置参数
    这些传播机制都是修饰被调用者的,也就是这里的B

    @Transactional(propagation=Propagation.REQUIRES_NEW)
    public void updateAcct(TradeData trade) throws Exception {...}
    
    • 1
    • 2

    7种事务传播机制:

    以下事务传播机制都用这个例子解释:有A方法,B方法两个方法,A调用B
    (如果A、B中都没有事务,那就不存在什么事务传播机制了,所以其中一个或都有事务才讨论事务传播机制)

    方法A是一个事务的方法,方法A执行过程中调用了方法B,那么方法B有无事务以及方法B对事务的要求不同都会对方法A的事务具体执行造成影响,同时方法A的事务对方法B的事务执行也有影响,这种影响具体是什么就由两个方法所定义的事务传播类型所决定。

    REQUIRED(Spring默认的事务传播类型 required:需要、依赖、依靠):如果当前没有事务,则自己新建一个事务,如果当前存在事务则加入这个事务
    当A调用B的时候:如果A中没有事务,B中有事务,那么B会新建一个事务;如果A中也有事务、B中也有事务,那么B会加入到A中去,变成一个事务,这时,要么都成功,要么都失败。(假如A中有2个SQL,B中有两个SQL,那么这四个SQL会变成一个SQL,要么都成功,要么都失败)

    SUPPORTS(supports:支持;拥护):当前存在事务,则加入当前事务,如果当前没有事务,就以非事务方法执行
    如果A中有事务,则B方法的事务加入A事务中,成为一个事务(一起成功,一起失败),如果A中没有事务,那么B就以非事务方式运行(执行完直接提交);

    MANDATORY(mandatory:强制性的):当前存在事务,则加入当前事务,如果当前事务不存在,则抛出异常。
    如果A中有事务,则B方法的事务加入A事务中,成为一个事务(一起成功,一起失败);如果A中没有事务,B中有事务,那么B就直接抛异常了,意思是B必须要支持回滚的事务中运行

    REQUIRES_NEW(requires_new:需要新建):创建一个新事务,如果存在当前事务,则挂起该事务。
    B会新建一个事务,A和B事务互不干扰,他们出现问题回滚的时候,也都只回滚自己的事务;

    NOT_SUPPORTED(not supported:不支持):以非事务方式执行,如果当前存在事务,则挂起当前事务
    被调用者B会以非事务方式运行(直接提交),如果当前有事务,也就是A中有事务,A会被挂起(不执行,等待B执行完,返回);A和B出现异常需要回滚,互不影响

    NEVER(never:从不): 如果当前没有事务存在,就以非事务方式执行;如果有,就抛出异常。就是B从不以事务方式运行
    A中不能有事务,如果没有,B就以非事务方式执行,如果A存在事务,那么直接抛异常

    NESTED(nested:嵌套的)嵌套事务:如果当前事务存在,则在嵌套事务中执行,否则REQUIRED的操作一样(开启一个事务)
    如果A中没有事务,那么B创建一个事务执行,如果A中也有事务,那么B会会把事务嵌套在里面。

    什么叫嵌套呢?
    A是父事务,B是子事务

    NESTED嵌套事务 和REQUIRES_NEW的区别
    REQUIRES_NEw是新建一个事务并且新开启的这个事务与原有事务无关,而NESTED则是当前存在事务时(我们把当前事务称之为父事务)会开启一个嵌套事务(称之为一个子事务)。在NESTED情况下父事务回滚时,子事务也会回滚,而在REQUIRES_NEw情况下,原有事务回滚,不会影响新开启的事务。
    和REQUIRED的区别
    REQUIRED情况下,调用方存在事务时,则被调用方和调用方使用同一事务,那么被调用方出现异常时,由于共用一个事务,所以无论调用方是否catch其异常,事务都会回滚而在NESTED情况下,被调用方发生异常时,调用方可以catch其异常,这样只有子事务回滚,父事务不受影响

    先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦

  • 相关阅读:
    怎样自学黑客技术_黑客/网络安全入门资料
    SQL语言之数据库与表的操作
    (附源码)springboot毕业生弃置物品交易系统 毕业设计 231151
    2023自动驾驶 车道线检测数据集
    漫画 | 编程语言三巨头的陨落
    365包包模式讲解
    MySQL 8.0 主从复制重建流程(从主库数据文件备份恢复)
    Flume (六) --------- Flume 数据流监控
    xampp安装包含的组件有(php,perl,apche,mysql)
    vue+vite+ts添加eslint校验和代码提交校验
  • 原文地址:https://blog.csdn.net/m0_67393828/article/details/126117071