Spring 七种事务传播性介绍

news2024/9/22 11:40:45

作者:vivo 互联网服务器团队 - Zhou Shaobin

本文主要介绍了Spring事务传播性的相关知识。

Spring中定义了7种事务传播性:

  • PROPAGATION_REQUIRED 

  • PROPAGATION_SUPPORTS

  • PROPAGATION_MANDATORY

  • PROPAGATION_REQUIRES_NEW

  • PROPAGATION_NOT_SUPPORTED

  • PROPAGATION_NEVER

  • PROPAGATION_NESTED

在Spring环境中,含有事务的方法嵌套调用,事务是如何传递的规则,以及每种规则是如何开展工作的。文章还提到每种事务传播性是如何使用的,方便读者依据实际的场景,使用不同的事务规则。

一、什么是Spring事务的传播性

Spring 事务传播性是指, 在Spring的环境中,当多个含有事务的方法嵌套调用时,每个事务方法都处于自己事务的上下文中,其提交或者回滚行为应该如何处理。

通俗讲,就是当一个事务方法调用另外一个事务方法时,事务如何跨上下文传播。

图片

1)当事务方法A调用事务方法B时,事务方法B是合并到事务方法A中,还是开启新事务?

2)当事务方法B抛出异常时  ,在合并事务或者开启新的事务的场景中,事务的回滚是如何处理的 ?

以上事务的处理规则,都取决于事务传播级别的设置。

二、事务的传播性都有哪些行为

图片

事务的传播行为,主要分为三种类型,分别是:支持当前事务不支持当前事务嵌套事务

2.1 支持当前事务

REQUIRED:默认的事务传播级别,表示如果当前方法已在事务内,该方法就在当前事务中执行,否则,开启一个新的事务并在其上下文中执行。

SUPPORTED:当前方法在事务内,则在其上下文中执行该方法,否则,开启一个新的事务。

MANDATORY:必须在事务中执行,否则,将抛出异常。

2.2 不支持当前事务

REQUIRES_NEW:无论当前是否有事务上下文,都会开启一个事务  。如果已经有一个事务在执行 ,则正在执行的事务将被挂起 ,新开启的事务会被执行。

事务之间相互独立,互不干扰。

NOT_SUPPORTED:不支持事务,如果当前存在事务上下文,则挂起当前事务,然后以非事务的方式执行。

NEVER:不能在事务中执行,如果当前存在事务上下文,则抛出异常。

2.3 嵌套事务

NESTED:嵌套事务,如果当前已存在一个事务的上下文中,则在嵌套事务中执行,如果抛异常,则回滚嵌套事务,而不影响其他事务的操作。

三、每种事务的传播性如何工作

3.1 REQUIRED  

默认的事务传播行为,保证多个嵌套的事务方法在同一个事务内执行,并且同时提交,或者出现异常时,同时回滚。

这个机制可以满足大多数业务场景。

图片

例子 :

图片

图片

1)类TestAService的方法通过声明式事务的方式,加上了事务注解@Transactional ,并设置事务的传播性为REQUIRED。

2)调用者调用TestAService的A方法时,如果调用者没有开启事务,那么A方法会开启一个事务。

A方法的具体执行过程如下 :

a. 执行insert,但没有提交;

b. 调用TestBServcie的B方法,由于B方法也声明了事务,并且传播性是REQUIRED,所以方法B的事务,合并到方法A开启的事务中。

c. 方法B执行insert操作,此时也没有提交。

3)由于这两个方法的操作都在同一个事务中执行,当这两个方法所有操作执行成功之后,提交事务。

嵌套调用链路:

图片

当方法B 执行时抛出了 Exception 异常后,事务是如何处理的 ?

1)方法B声明了事务,insert操作会回滚

2)由于方法A和方法B 同属一个事务,方法A也会执行回滚,由此说明该规则保证了事务的原子性。

嵌套调用,异常后的链路:

图片

如果 方法B 抛出异常后,方法A 使用 try-catch 处理了方法B的异常(如下代码),并没有向外抛出,此时事务又如何处理的 ?

图片

方法A也会回滚。

从事务的特性我们可知,事务具有原子性。方法A和方法B同属一个事务,当方法B抛出异常,触发回滚操作后,整个事务的操作都会回滚。

因此,Spring 在处理事务过程中,当事务的传播性设置为REQUIRED,在整个事务的调用链上,任何一个环节抛出的异常都会导致全局回滚。

3.2 REQUIRES_ NEW

每次都开启一 个新的事务。

图片

例子:

图片

上面例子中,方法B的传播性设置为 REQUIRES_NEW,方法A仍然是REQUIRED,当A调用B时,具体调用链路如下:

图片

具体执行过程:

  • 方法A被执行前,如果调用者没有开启事务,方法A开启一个事务1,然后执行insert ,此时没有提交;

  • 方法B的事务传播性设置为REQUIRES_NEW,当被方法A调用时,此时方法A的事务1会被挂起,方法B开启自己的事务2,然后执行insert,此时并没有提交;

  • 当方法B执行完毕后,提交事务2;

  • 恢复事务1,最终提交。

当 方法B 执行时抛出了异常,会发生什么?

方法B的insert操作会被回滚掉,方法A不受影响。但这里有个前提,方法A需要try-catch方法B的异常,使其异常不会往上传递,从而导致方法A接收到异常,导致回滚。

图片

3.3  SUPPORTED

当外层方法A存在事务,方法B加入到当前事务中,以事务的方式执行。

图片

当外层方法A不存在事务,方法B不会创建新的事务,以非事务的方式执行。

图片

例子1:

图片

图片

以上例子,方法A没有加事务注解,方法B的加了事务注解,并且传播为SUPPORTS。

具体执行过程:

  • 方法A以非事务的方式执行insert操作。

  • 方法B被调用,由于其外层事务A没有开启事务,方法B也是以非事务方法执行insert操作。

图片

例子2:

图片

以上例子,方法A和B都加上了事务注解,其中方法A的传播性为REQUIRED,方法B的传播性为SUPPORTS。

具体执行过程:

  • 如果方法A的调用方没有开启事务,则方法A开启事务,并执行insert操作,但没有提交;

  • 方法B被调用,由于其外层方法A开启了事务,因此方法B加入到方法A开启的事务中,并执行insert,但没有提交;

  • 当事务中的所有操作执行成功后,事务提交。

图片

3.4  NOT_SUPPORTED

不支持事务。

如果外层方法存在事务,则挂起外层事务,以非事务方式执行,执行完毕后,恢复外层事务。

图片

例子:

图片

以上例子:方法A和B都加上了事务注解,方法A的传播性为REQUIRED,方法B为NOT_SUPPORTED。

具体执行过程:

  • 如A的调用方没有开启事务,方法A开启事务,并执行insert,但没有提交。

  • 方法A调用方法B时,方法B的传播性为NOT_SUPPORTED,不支持事务,然后挂起外层方法A的事务,方法B以非事务的方式执行insert。

  • 方法B执行完毕后,恢复方法A的事务,最终提交事务。

调用链路过程:

图片

3.5 NEVER

不支持事务

当外层方法A开启了事务,方法B抛出异常

图片

例子:

图片

以上代码,两个方法都打上了事务注解,方法A的传播性是REQUIRED,方法B的传播性是NEVER。

具体执行过程:

  • 方法A开启事务,执行insert,没有提交。

  • 含有事务的方法A调用方法B,方法B的传播性是NEVER,表示不支持事务,因此方法B抛出异常。

  • 方法A的事务执行回滚。

图片

3.6 MANDATORY

必须在事务中执行。

如果外层方法A没有开启事务,方法B抛出异常。

图片

如果外层方法A开启了事务,方法B加入事务,方法A&B在同一事务中执行。

图片

例子:

图片

以上例子,方法A没有加事务注解,方法B 的传播性为 MANDATORY。

具体执行过程:

  • 方法A的调用方如果本身没有开启事务,方法A执行前不会开启事务。

  • 当非事务方法A调用方法B时,由于方法B的传播性为MANDATORY,必须在事务中执行,条件不满足,抛出异常。

图片

3.7 NESTED

嵌套事务

  • 如果外层方法A不存在事务,内层方法B的规则与REQUIRED 一致。

  • 如果外层方法A存在事务,内层方法B做为外层方法A事务的子事务执行,两个方法是一起提交,但子事务是独立回滚。

    内层方法B抛出异常,则会回滚方法B的所有操作,但不影响外层事务方法A。(方法A需要try-catch子事务,避免异常传递到父层事务)

    外层方法A回滚,则内层方法B也会回滚。

  • 该传播性的特点是可以保存状态点,当回滚时,只会回滚到某一个状态点,保证了子事务之间的独立性,避免嵌套事务的全局回滚。

图片

例子:

图片

以上例子,方法A的传播性为REQUIRED,方法B为NESTED。

具体执行过程:

  • 方法A执行时,如调用方没有开启事务,则开启一个事务。

  • 方法B被外层方法A调用时,因为方法B的传播性为NESTED,方法B在此处建立savepoint,标记insert行为。

  • 当方法B抛出异常,其insert操作会回滚,但只会回滚到savepoint,(前提是方法A要try-catch方法B,使方法B的异常不会往外传递)。

  • 方法B回滚后,方法A的事务提交。

调用链路:

图片

四、总结

本文解释了Spring框架中的事务传播性,即多个业务方法之间调用时事务如何处理的规则。Spring提供了七种传播级别,如PROPAGATION_REQUIRED、PROPAGATION_REQUIRES_NEW等。

每种级别都有适用场景和限制,本文提供了一些示例,介绍了声明式事务如何使用,每种事务的规则,产生哪种行为,当方法抛出异常时,事务的提交和回滚是如何被处理的。正确处理事务对于任何企业级应用程序都是必要的,了解Spring事务传播性是构建高效、可靠和可扩展应用程序的关键。

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

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

相关文章

光明源智能:智慧厕所系统,打造智慧化科技智能生活

在这个科技飞速发展的时代,我们的生活正经历着一场全面的革命,而这场变革不仅仅局限于我们的工作和娱乐,甚至涉及我们生活中最私密的空间之一——卫生间。随着科技与卫生的巧妙融合,智慧厕所系统正日益成为一个引人注目的焦点。本…

构建高效秒杀系统的设计原理及注意事项

😄 19年之后由于某些原因断更了三年,23年重新扬帆起航,推出更多优质博文,希望大家多多支持~ 🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志 🎐 个人CSND主页——Mi…

5G-A,一根蓄满能量的弹簧

光阴转瞬,恍然间2024已经来到身边。经历了2023年全球AI技术大爆发,以及智能汽车、虚拟现实、自主科技等诸多领域取得关键进展。想必大家希望知道在新一年中有哪些值得期待的科技增长空间。 如果是这样,那么不妨将目光投向5G-A。 与其他科技领…

轻松入门:Anaconda 在 PyCharm 中的配置与应用指南

1 Anaconda Anaconda 和 Conda 是两个相关但不同的概念。 Anaconda 是一个免费且开源的发行版,包含了 Python 和 R 语言的数据科学和机器学习相关的众多包,它包括 Conda、Python、Jupyter Notebook 等多个科学计算和数据科学中常用的应用。 Anaconda 通过…

unity中0GC优化方案《zstring》

文章目录 序言简介GC带来的问题性能瓶颈玩家体验受损 使用方式 序言 游戏开发秉承遇到好东西要分享,下面介绍zstring,感谢作者开源无私奉献 源码地址:https://github.com/871041532/zstring 简介 GC带来的问题 性能瓶颈 GC暂停主线程执行…

你珍藏的那个表情包女孩,现在滤镜碎了一地。

♥ 为方便您进行讨论和分享,同时也为能带给您不一样的参与感。请您在阅读本文之前,点击一下“关注”,非常感谢您的支持! 文|猴哥聊娱乐 编辑|侯欢庭 七年前,一个年仅三岁的小女孩以其无邪的表情包风靡网络&#xff0…

科锐16位汇编学习笔记 03 汇编指令

指令种类 数据传送指令算数运算类指令位操作类指令串操作类指令控制转移类指令处理器控制类指令 数据传送类指令 传送类指令不影响标志位,**除了标志位传送指令外。** 传送指令MOV(move) 说明 ​ 把一个字节或字的操作数从源地址传送至…

安全与认证Week3 Tutorial+历年题补充

目录 1) 什么是重放攻击? 2)什么是Kerberos系统?它提供什么安全服务? 3)服务器验证客户端身份的一种简单方法是要求提供密码。在Kerberos中不使用这种身份验证,为什么?Kerberos如何对服务器和客户机进行身份验证? 4) Kerberos的四个要求是什么?Kerberos系…

Python IDE Pycharm服务器配置方法并结合内网穿透工具实现远程开发

文章目录 一、前期准备1. 检查IDE版本是否支持2. 服务器需要开通SSH服务 二、Pycharm本地链接服务器测试1. 配置服务器python解释器 三、使用内网穿透实现异地链接服务器开发1. 服务器安装Cpolar2. 创建远程连接公网地址 四、使用固定TCP地址远程开发 本文主要介绍如何使用Pych…

位移贴图还原电影3D角色

在线工具推荐: 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 位移贴图(Displacement Map)在电影制作中是一…

Databend 的安装配置和使用

介绍 Databend 是一个内置在 Rust 中的开源、弹性和工作负载感知的云数据仓库,为 Snowflake 提供了具有成本效益的替代方案,专门对最大的数据集进行复杂分析而设计。 性能: 在存储对象上,能快速进行数据分析。没有索引和分区&a…

扩展 apiserver 连接认证 ip, apiserver证书更新

本文来自我的博客地址 文章目录 问题场景:问题分析:问题解决:查看 apiserver 证书支持的 ip 或 host使用 openssl 生成证书:再次查看 apiserver 证书支持的 ip 或 host 再次尝试将 master 加点加入参考 问题场景: k8s 1.28.1 集群后期新增 vip apiserver 证书不支持 vip 引入…

【LLM】大型语言模型:2023年完整指南

Figure 1: Search volumes for “large language models” 近几个月来,大型语言模型(LLM)引起了很大的轰动(见图1)。这种需求导致了利用语言模型的网站和解决方案的不断开发。ChatGPT在2023年1月创下了用户群增长最快…

工智能基础知识总结--导出SVM要优化的问题

导出SVM要优化的问题 对于上图中这样一个二分类线性可分问题,期望找到一个分类超平面将正负类分开,SVM就是一个用来寻找这样的分类超平面的算法。 定义正负类的标签分别为1、-1,分类超平面的表达式为 f ( x ) = w T x + b f(x)=w^Tx+b

vue的插值语法,vue指令系统,style和class

官网:https://cn.vuejs.org/ 文档3:https://cn.vuejs.org/ 文档2:https://v2.cn.vuejs.org/ M-V-VM架构 mvvm 前端vue架构 M:model 数据层 V:view 用户视图层 VM:viewmodel 连接数据和视图…

技术概述:ARMv8体系结构

John Goodacre, Director Program Management ARM Processor Division, November 2011 背景:ARM体系结构 从ARM精简指令集体系结构提出到现在已经有20多年了;ARMv7系列处理器是在ARMv4基础上设计的,随着ARMv7系列处理器大量应用&#xff0…

每天一杯羊奶,让身体更健康

每天一杯羊奶,让身体更健康 羊奶作为一种天然的健康饮品,越来越受到人们的关注和喜爱。它不仅口感醇厚,营养丰富,而且具有独特的保健功效。今天,小编羊大师带大家详细介绍一下每天喝一杯羊奶对身体的好处。 羊奶中的…

首发!全志T527第一款核心板,高性能8核处理器带AI NPU

今天,米尔电子联合战略合作伙伴全志科技,隆重发布第一款T527核心板及开发板。基于全志T527高性能可选AI功能MPU,配备八核A55高性能处理器,RISC-V协处理器,支持2Tops NPU,满足边缘智能AI加速应用&#xff1b…

“奶茶妹妹”章泽天被曝生双胞胎,偷拍照流出

♥ 为方便您进行讨论和分享,同时也为能带给您不一样的参与感。请您在阅读本文之前,点击一下“关注”,非常感谢您的支持! 文|猴哥聊娱乐 编辑|侯欢庭 去年九月的某一天,一位网友在国外的一家商场偶遇了章泽天和刘强东…

QT5.14 实现ModbusTCP客户端 Demo

本文在QT5.14平台,基于QModbusClientTcp类,实现了客户端对单个寄存器的读写,用ModbusSlave做服务器做测试。 1.界面 (1)更改读按钮的名称为bt_Read (2)更改写按钮的名称为bt_Write 2.修改pro文件的第三行 greaterThan(QT_MAJOR_VERSION, 4)…