关于 Spring 中事务的嵌套,你了解多少?

news2024/12/23 22:10:16

Spring事务的的详细理解,事务嵌套解析,以及事务失效的场景解惑

想要了解Spring的事务嵌套,我们先了解一下Spring的七种事务传播属性各自表示的意思

  1. propagation_requierd:如果当前没有事务,就新建一个事务,如果已存在一个事务中,加入到这个事务中,这是最常见的选择。

  2. propagation_supports:支持当前事务,如果没有当前事务,就以非事务方法执行。

  3. propagation_mandatory:使用当前事务,如果没有当前事务,就抛出异常。

  4. propagation_required_new:新建事务,如果当前存在事务,把当前事务挂起。

  5. propagation_not_supported:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

  6. propagation_never:以非事务方式执行操作,如果当前事务存在则抛出异常。

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

了解了这七种传播属性表示的意思,接下来在说具体的解释

详解Spring的事务传播属性以及在写代码的过程中发生嵌套并发生事务失效的场景

再说这些之前,大家先要清除一个问题,Spring的事务是怎么实现的?

Spring本身是没有事务的,只有数据库才会回有事务,而Spring的事务是借助AOP,通过动态代理的方式,在我们要操作数据库的是时候,实际是Spring通过动态代理进行功能扩展,在我们的代码操作数据库之前通过数据库客户端打开数据库事务,如果代码执行完毕没有异常信息或者是没有Spring要捕获的异常信息时,再通过数据库客户端程序提交事务,如果有异常信息或者是有Spring要捕获的异常信息,再通过数据库客户端程序回滚事务,从而达到控制数据库事务的目的。

1、Spring的事务的简单原理示意图,请看下图

2、Spring的Transactional注解默认情况下的传播属性是什么呢,请看一下Transactional的源码:下图所示(所以在默认的情况下我们加了Transactional 就会有事务)

3、第1、第2两部分看明白之后,再来说一下Spring事务嵌套会发生的情况

3.1、在同一个类中发生事务嵌套的情况

答案是会回滚的,原因是什么呢?接着看下边的示意图

看上边的示意图你一定会明白了吧,原因还是因为代理的时候,直接把没有事务的方法包在了有事务的代理方法里边了自然就有事务了,这样说够明确吗?不够的话可以留言,给你解答一下

3.2 再看一种嵌套的方式

答案:这时候调用test02,test01有异常发生时是不会回滚的

为什么呢?其实如果上边的你理解了下边就很容易理解了

3.3 这些明白了 后边的就更容易明白了,再看一个例子

上述3.3中的例子,如果调用test02 的话,当程序发生异常,test01会不会回滚呢?

答案是会回滚的 原因和3.1中的情况类似

所以综合上边说的,在同一个类中事务嵌套的话,最终的结果应该是取决于最外层的方法事务的传播特性

4、以上是在一个相同的类中的情况,如果是不同的类中的方法嵌套调用是什么样子的呢?

4.1 我们来看下列一种情况

在TestService3中调用TestService4中的没有事务的方法,会发生什么呢?TestService4中的test41方法发生异常会回滚吗?

答案:会的

为什么呢请看下图:

4.2 我们再来看一个情况

TestService3中的方法是有事务的,TestService4中的方法是以非事务的方式运行,如果存在事务就挂起事务,那么自然就没有事物了

所以上述的情况就是,如果TestService4中的方法报出异常,则TestService3中的数据可以回滚,但是TestService4中操作的数据是不会回滚的

再有其他的情况大家根据上述的原理,然后结合传播属性的特点去套就可以了

总结4中的案例得到的结论是,如果是不同的类的事务嵌套的话,外层的方法按照外层的事务传播属性执行,内层的传播属性按照内层的传播属性的特点去运行

5、下边介绍一些目前我知道的Spring事务会失效的情况

5.1 事务方法访问修饰符不是public,导致事务失效

比如下图中的代码

其实如果是JDK的动态代理 就不允许这种情况,因为JDK动态代理需要有接口,而接口中是不能有 私有方法的,如果是CGLIB动态代理的话也是不允许的代理private方法的

5.2 如果事务方法是static、final的,同样无法通过动态代理,事务也是不会生效的。

Spring的声明式事务是基于动态代理实现的,我们无法重写final修饰的方法;不管是JDK动态代理还是Cglib的动态代理,就是要通过代理的方式获取到代理的具体对象,而static方法修饰的方法是属于类对象的,不属于任何实例对象,所以static方法不能被重写也就是说static方法也不被进行动态代理。

5.3 操作的数据库表如果本身不支持事务 那么配置的Spring事务 也会失效

5.4 代码中的异常被 catch 住,而且没有异常再次抛出,也会让spring的事务失效,如下图中所示 事务就会失效

想要 避免上述的失效的话 可以 在catch 住后在catch块中再次 抛出Spring事务支持的异常,就可以了

5.5 多线程的调用导致事务的失效,例如 下边的案例 会导致 test31的事务失效

解释:原因是因为 test31中操作数据要回滚,需要有异常抛出才可以回滚,但是由于线程异步运行这种写法,test31和test41分别是两个独立的事务,他们的数据库链接都可能是不同的,要想回滚则test31和test41都应该有异常抛出才可以。

但是test31所在的线程没有捕获到test41所在的子线程的异常所以没有回滚,之所以没有捕获到test41所在的线程的异常是因为test41相对test31是异步运行,可能test31已经运行完了,但是test41还没有运行完,所以在写这种代码的时候大家可以使用thread.setUncaughtExceptionHandler方法来处理线程内部的异常,也就是当thread报出异常的时候可以在这个方法中再次抛出异常这样可以触发外部事务的回滚,或者也可以采用下列的代码

@Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
public  void test31() throws ExecutionException, InterruptedException {
    Map<String,Object> map=new HashMap<>();
    map.put("id",3);
    map.put("quantity",300);
    int i = testDao.updateStock(map);

    FutureTask task=new FutureTask(new Callable() {
        @Override
        public Object call() throws Exception {
            testService4.test41();
            return "ok";
        }
    });
    Thread thread = new Thread(task);

    thread.start();
    //等待执行结果,当有异常的时候在这里就可以获取到异常传递给test31触发他的回滚
    Object ok = task.get();
    System.out.println("=============OK");
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/649369.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

简单的TCP网络程序·单进程(后端服务器)

目录 文件1&#xff1a;tcpServer.cc 文件2&#xff1a;tcpServer.hpp 1.提出日志概念 -- 在后续完善 日志格式 -- 暂定简单的打印功能 2.创建套接字 SOCK_STREAM -- socket参数 3.bind自己的套接字 4.设置socket 为监听状态 * 新接口1&#xff1a;listen 函数1&…

Spring Boot进阶(46):集成Jackson之快速入门 | 超级详细,建议收藏

1. 前言&#x1f525; 在上一期《SpringBoot之Jackson配置全局时间日期格式》文中提到Jackson&#xff0c;了解到有很多小伙伴对它很感兴趣&#xff1b;顾这一期&#xff0c;我就重点带着大家以最基础的教学方式领大家入门&#xff0c;废话不多说&#xff0c;咱们这就开始。 这…

(字符串) 925. 长按键入 ——【Leetcode每日一题】

❓925. 长按键入 难度&#xff1a;简单 你的朋友正在使用键盘输入他的名字 name。偶尔&#xff0c;在键入字符 c 时&#xff0c;按键可能会被长按&#xff0c;而字符可能被输入 1 次或多次。 你将会检查键盘输入的字符 typed。如果它对应的可能是你的朋友的名字&#xff08;…

【大学物理实验】表面张力

文章目录 选择题选择题 液体表面张力只存在与液体的: A. 内部 B. 底部 C. 表面 D. 表面和内部 正确答案: C 本实验中,下面哪一件测量仪器(工具)是不需要的: A. 力敏传感器 B. 数字电压表 C. 游标卡尺 D. 物理天平 正确答案: D 关于吊环从液体中拉脱力(即最大表面张力)…

距离和相似性度量

文章目录 1. 距离度量1.1 欧几里得距离(Euclidean Distance)1.2 明可夫斯基距离(Minkowski Distance)1.3 曼哈顿距离(Manhattan Distance)1.4 切比雪夫距离(Chebyshev Distance)1.5 马哈拉诺比斯距离(Mahalanobis Distance) 2. 相似性度量2.1 向量空间余弦相似度(Cosine Simila…

盘点五种最常用加密算法!

大家好&#xff0c;我是老三&#xff0c;大家都知道我是一个臭做支付的&#xff0c;支付常常要和一些加签、验签&#xff0c;加密、解密打交道&#xff0c;今天&#xff0c;就给大家来盘点一下最常见的5种加密算法。 前言 大家平时的工作中&#xff0c;可能也在很多地方用到了…

封神榜科技成果 - 国产训练大模型

封神榜科技成果 Fengshenbang 1.0: 封神榜开源计划1.0中英双语总论文&#xff0c;旨在成为中文认知智能的基础设施。 BioBART: 由清华大学和IDEA研究院一起提供的生物医疗领域的生成语言模型。(BioNLP 2022) UniMC: 针对zero-shot场景下基于标签数据集的统一模型。(EMNLP 2022)…

STM32单片机(六)TIM定时器 -> 第三节:TIM输出比较

❤️ 专栏简介&#xff1a;本专栏记录了从零学习单片机的过程&#xff0c;其中包括51单片机和STM32单片机两部分&#xff1b;建议先学习51单片机&#xff0c;其是STM32等高级单片机的基础&#xff1b;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 &#xff1a;适用于想要…

『2023北京智源大会』视觉与多模态大模型

『2023北京智源大会』视觉与多模态大模型 文章目录 一. Drag Your GAN: Interactive Point-based Manipulation on the Generative Image Manifold | 潘新钢 | 南洋理工大学1. Image Manipulation(图像编辑)背景2. Drag Your GAN 二. Machine Learning for 3D Content Creatio…

实验篇(7.2) 14. 站对站安全隧道 - 多条隧道负载均衡(上)(FortiGate-IPsec) ❀ 远程访问

【简介】IPsec VPN虽然价廉物美&#xff0c;但是由运营商原因&#xff0c;经常会出访问慢、不稳定甚至断开的情况&#xff0c;好在现在大多数企业都有二条甚至更多条宽带&#xff0c;我们可以创建多条IPsec VPN&#xff0c;来保证正常访问。 实验要求与环境 OldMei集团深圳总部…

友盟分享之新浪微博站(签名apk下载)

适用环境&#xff1a; 1 单独集成新浪微博分享 2 友盟分享新浪微博 集成步骤&#xff1a; 1 注册新浪微博开发者账号 新浪微博开放平台-首页 2 选择要接入的应用类型 根据官网提示输入对应资料&#xff0c;进行申请 4 创建应用的时候&#xff0c;Android需要输入签名&#x…

NFC无源电子墨水屏

NFC电子纸造就无源可视 电子墨水标签 NFCE-paper For NFC Batteryless E-ink Tag 产品参数 产品型号 PN29_S 尺寸(mm) 95*46.4*5.4mm 显示技术 电子墨水屏 显示区域(mm) 29(H) * 66.9(V) 分辨率(像素) 296*128 像素尺寸(mm) 0.227*0.226 显示颜色 黑/白 视…

摩尔定律放缓后,AMD应如何引领自适应的风潮?

编者按&#xff1a;自适应计算如何为核心市场带来动力&#xff1f;近日&#xff0c;在AMD“自适应和嵌入式产品技术日”活动日上&#xff0c;AMD 全球副总裁唐晓蕾表示&#xff0c;创新是驱动发展的引擎&#xff0c;百行百业的数字化与智能化转型离不开创新输送的源源不断的强劲…

【监控】Zabbix:企业级开源监控解决方案

文章目录 一、zabbix的基本概述二、zabbix的构成三、zabbix的监控对象四、zabbix的常用术语五、zabbix的工作流程六、zabbix进程详解七、zabbix的监控框架7.1 三种架构模式的架构图如下&#xff1a;7.2 每个模块的工作职责&#xff1a; 八、zabbix源码安装及部署一、服务端安装…

电子工程师,一起来聊聊PCB板上的Mark点吧

在PCB设计中&#xff0c;电子工程师需要注意很多方面&#xff0c;新手工程师经常会忽略Mark点&#xff0c;但资深工程师们却对Mark点又爱又恨&#xff0c;甚至不得不花时间耗费在Mark点上&#xff0c;为什么Mark点如此重要&#xff1f;该如何设计Mark点&#xff1f; 一、Mark点…

Linux基础IO - 文件系统 | 软硬链接

之前的文章中我们与文件有关的内容谈论的都是被打开的文件&#xff0c;那么如果文件没有被打开呢&#xff1f;这样文件就一定不再内存中&#xff0c;只能在磁盘外设中存储&#xff0c;本文中我们就来讲述磁盘中文件的相关知识。 磁盘的物理存储结构 一个磁盘由多个盘片叠加而…

如何撰写高效且实用的Prompt

很多人说GPT并没有什么让人惊艳的地方&#xff0c;但实际上&#xff0c;他们并没有发挥好它的潜能。在很多情况下&#xff0c;他们往往没有使用恰当的prompt。一个恰到好处的prompt就如同魔法师在施展魔法时所需要吟唱的咒语&#xff0c;只有那些正确无误的咒语&#xff0c;才能…

Zstack实习-基础知识总结归纳-持续更新

什么是虚拟化&#xff1f; 虚拟化技术是一种将物理计算资源&#xff0c;如服务器、存储和网络等&#xff0c;转化成虚拟的逻辑资源的技术。通过虚拟化技术&#xff0c;可以将多个独立的操作系统运行在同一台物理计算机上&#xff0c;实现资源的共享&#xff0c;提高硬件的利用率…

商业智能之“道、法、器”——企业级BI能力构建指南

一个企业级BI项目看似简单&#xff0c;但实际建设难度却远超想象。如何从0到1搭建BI项目&#xff0c;有没有详细的实施步骤&#xff0c;有没有合适的BI工具推荐&#xff0c;这是很多企业在上BI系统前心中的疑问。因此&#xff0c;本文会详细探讨企业BI能力构建&#xff0c;到底…

【业务功能篇26】 ROW_NUMBER() 排名函数 给表单数据增加序列号

业务场景&#xff1a; 当业务在进行月报报表制作时&#xff0c;会有些模块是需要填充当前月的top问题单&#xff0c;那么这些问题单&#xff0c;在第一列就要给标记序列号从1开始的序号&#xff0c;所以这个序号是根据业务选择的问题单后&#xff0c;在根据当前问题单记录进行的…