Spring 事务和事务传播机制

news2024/11/22 21:42:04

1.什么是事务(为什么要有事务)

        事务就是将一组操作封装成一个执行单元(封装到一起),要么一起成功,要么一起失败。

在打账的情景上,A向B转账200 元,A的账户-200.B的账号+200,但是如果是一些特殊情况,A的账号-200之后,但是B账号并没有加上这个200元子的话,就会出现很大的问题,而出现这一大问题的原因,就是没有将转账这个业务变成事务。这里也体现了事务的原子性一大特征。

2.事务的实现

        手动、自动的实现俩种方式。手动就是编程的方式(手写代码),另一种自动就是声明式(注解)。

2.1 手动的实现:

        

 

2.2 注解实现

        注解实现极为简单就是在方法前加上个 @Transactional 注解就ok 了,如果方法报错,就将所有已经进行的操作进行回滚,如果没有错误,那就正常执行不进行回滚。

        

@Transactional 可以⽤来修饰⽅法或类:
        修饰⽅法时:需要注意只能应⽤到 public ⽅法上,否则不⽣效。推荐此种⽤法。
        修饰类时:表明该注解对该类中所有的 public ⽅法都⽣效

2.3 @Transactional原理

@Transactional 是基于 AOP 实现的,AOP ⼜是使⽤动态代理实现的。如果⽬标对象实现了接⼝,默认情况下会采⽤ JDK 的动态代理,如果⽬标对象没有实现了接⼝,会使⽤ CGLIB 动态代理。
@Transactional 在开始执⾏业务之前,通过代理先开启事务,在执⾏成功之后再提交事务。如果中途遇到的异常,则回滚事务。
 


常见的参数设置: 

 


        

3.事务的隔离级别

Spring事务管理框架支持数据库的四种隔离级别,可以在@Transactional注解中设置isolation属性来指定所需的隔离级别。具体隔离级别如下:

  1. DEFAULT:使用默认隔离级别,由底层数据源管理器决定。

  2. READ_UNCOMMITTED(读未提交):事务可以读取到其他事务修改但未提交的数据,可能会导致脏读问题的出现。

  3. READ_COMMITTED(读已提交):事务只能读取到其他事务已经提交的数据,可以避免脏读问题,但仍可能会出现不可重复读和幻读问题。

  4. REPEATABLE_READ(可重复读):事务在执行期间可以重复读取相同的记录,并保证读到的是事务开始时的状态。可以避免脏读和不可重复读问题,但仍可能会出现幻读问题。

  5. SERIALIZABLE(串行化):事务需要串行执行,完全避免了并发问题的出现,但同时也影响了数据库的并发性能。

事务的隔离级别是指在并发环境下多个事务之间隔离的程度,主要是为了避免各种并发问题的出现,如脏读、不可重复读和幻读等。


        常见的事务隔离级别有以下四种:

  1. READ UNCOMMITTED(读未提交):事务可以读取到其他事务修改但未提交的数据,可能会导致脏读问题的出现。

  2. READ COMMITTED(读已提交):事务只能读取到其他事务已经提交的数据,可以避免脏读问题,但仍可能会出现不可重复读和幻读问题。

  3. REPEATABLE READ(可重复读):事务在执行期间可以重复读取相同的记录,并保证读到的是事务开始时的状态。可以避免脏读和不可重复读问题,但仍可能会出现幻读问题。

  4. SERIALIZABLE(串行化):事务需要串行执行,完全避免了并发问题的出现,但同时也影响了数据库的并发性能。

下面详细介绍各种隔离级别的特点和应用场景:

  1. READ UNCOMMITTED(读未提交):该隔离级别下,由于事务可以读取到其他事务尚未提交的数据,因此可能会出现脏读问题。该隔离级别通常不应用于生产环境,仅用于特定的性能测试或调试场景。

  2. READ COMMITTED(读已提交):该隔离级别下,事务只能读取到其他事务已经提交的数据,可以避免脏读问题。但由于非锁定读取,依然可能会出现不可重复读和幻读问题。

  3. REPEATABLE READ(可重复读):该隔离级别下,事务在执行期间可以重复读取相同的记录,并保证读到的是事务开始时的状态。可以避免脏读和不可重复读问题,但仍可能会出现幻读问题。MySQL的默认隔离级别即为REPEATABLE READ。

  4. SERIALIZABLE(串行化):该隔离级别下,事务需要串行执行,完全避免了并发问题的出现。但同时也影响了数据库的并发性能,通常应用于对数据安全要求极高的场景,如银行、财务等系统。

● 脏读:⼀个事务读取到了另⼀个事务修改的数据之后,后⼀个事务⼜进⾏了回滚操作,从⽽导致第⼀个事务读取的数据是错误的
● 不可重复读:⼀个事务两次查询得到的结果不同,因为在两次查询中间,有另⼀个事务把数据修改了。
● 幻读:⼀个事务两次查询中得到的结果集不同,因为在两次查询中另⼀个事务有新增了⼀部分数据

 

4. 事务失效的场景

        4.1 try catch

         在try catch 将错误代码包裹之后,catch里面不加任何操作的话,是会出现问题的,出现这个现象的原因是,因为Spring中事务是会自动识别错误代码的,但是你如果加上了try catch的话就说明你是知道这里有错的,Spring就不会帮你识别了,也就不会自动的进行回滚操作了。

 可以看到并没有实现事务回滚操作。

 

        4.1解决方案:

1.你把这个错误抛出不就行了嘛 2.通过代码的方式手动回滚

第一种就是throw就行,第二种方式要讲一下:

        4.2 非public修饰方法

SpringBoot事务失效的场景有哪些? | Javaᶜⁿ 面试突击 (javacn.site)

注解只能在public修饰的方法使用。

        4.3 timeout超时

注解上是可以设置超时时间的,如果设置的时间比较小,而执行代码的时间大于设置的时间,就会导致本来要插入的数据没法正常插入。

        4.4 数据库不支持事务

        4.5 调用类内部的@Transactional方法

 本来是要进行回滚的,但实际情况是报错,但是数据还是存入到数据库中的。

5. Spring事务的传播机制

        Spring事务传播机制是指多个事务在互相调用的情况下,如何管理这些事务的提交和回滚。

Spring 提供了七种事务传播行为,分别是:

  1. REQUIRED(默认传播行为):如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
  2. SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务方式执行。
  3. MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
  4. REQUIRESNEW:创建一个新的事务,如果当前存在事务,则挂起该事务。
  5. NOTSUPPORTED:以非事务方式执行操作,如果当前存在事务,则挂起该事务。
  6. NEVER:以非事务方式执行操作,如果当前存在事务,则抛出异常。
  7. NESTED:如果当前存在事务,则在嵌套事务中执行;如果当前没有事务,则创建一个新的事务。

著作权归 JavaCN.site 所有 原文链接:https://www.javacn.site/spring/propagation.html

        我们通过支持当前事务和不支持当前事务和嵌套事务分为三类:

5.1 支持当前事务

        REQUIRED

        当前有事务就加入,没有就创建新的。

        SUPPORTS

        有事务就加入,没有就以非事务的方式执行。

        MANDATORY

        有事务就加入,没有就抛异常

5.2 不支持当前事务

        REQUIRESNEW

        创建一个新事务,如果有事务就将这个事务挂起

        NOTSUPPORTED

        以非事务的方式执行,如果有事务就挂机这个事务

        NEVER

        以非事务的方式执行,如果有事务就抛异常

5.3 嵌套事务

        NESTED

        如果当前是有事务就嵌套进这个事务中,如果没有事务就创建一个新的事务。

我们创建一个业务场景来简单理解一下这里的事务传播机制:

        我们先在controller层调用UserController类里面的UserService(service层),在user的service层有俩个操作:一是调用usermapper的add,另一个是调用了log的service层(进行logmapper的add)。

        

 

嵌套事务(NESTED)和加⼊事务(REQUIRED )的区别:

整个事务如果全部执⾏成功,⼆者的结果是⼀样的。
如果事务执⾏到⼀半失败了,那么加⼊事务整个事务会全部回滚;⽽嵌套事务会局部回滚,不会影
响上⼀个⽅法中执⾏的结果.

嵌套事务只所以能够实现部分事务的回滚,是因为事务中有⼀个保存点(savepoint)的概念,嵌套事务进⼊之后相当于新建了⼀个保存点,⽽滚回时只回滚到当前保存点,因此之前的事务是不受影响的

 

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

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

相关文章

基于直流微电网的光伏并网功率转换装置设计与运行仿真

摘要 微电网是目前国内外应用较为广泛的一种绿色可再生能源,近几年我国微电网产业的发展十分迅速。然后,越来越多的微电网系统建立并网,微电网产生的电能受外界因素影响较大,具有一定的随机性和波动性,给并网后的电力系…

SaaS 产品如何选择设计协作工具?

文章内容转载腾讯 CoDesign 随着互联网及其衍生技术的发展,企业比以往更依赖内容去吸引、去培养自己的用户,寻求转化。小鹅通就是在微信生态中帮助企业通过知识服务去实现内容分发和流量聚合,帮助企业沉淀用户,提供深度私域运营服…

回收站清空了怎么找回文件?3种办法恢复彻底删除文件!

电脑回收站大家都有一定的了解,只要在回收站的文件没有被删除的时候是可以还原的,但是回收站删除了,文件就无法直接恢复。回收站清空了怎么找回文件? 别着急,今天小编就分析几种恢复回收站删除数据的办法: 方法一&am…

(转载)从0开始学matlab(第8天)—matlab画图入门

1.基本画图方式 MATLAB 的扩展性和机制独立的画图功能是一个极其重要的功能.这个功能使数据画图变得十分简单 . 画一个数据图 , 首先要创建两个向量,由 x, y 构成 , 然后使用 plot 函数. 例如 , 假设我们要画出函数 yx -10x10 的图象 , 定义域为[ …

分享两组不同的3D VR卡片

最近某音上出现了很多VR视频,转动手机可以看到手机界面未显示出来的场景。这种事情我觉得我们也可以做到。 所以两种不同的3D VR卡片来了: 第一种是横向或上下可以拖动极大的距离。卡片上的信息会随着拖动移动,但不会显示更多的信息&#x…

二、LLC 谐振变换器

半桥 LLC 谐振变换器主电路结构 如图所示,半桥 LLC 谐振变换器主电路可以分为四个部分,即:逆变网络、谐振网络、变压器及整流滤波网络。两个 MOSFET(S1、S2)以及它们的体二极管(D1、D2)和寄生电…

svn清理以下路径失败显示乱码问题

报错: svn作为我们经常使用的版本管理服务器,在使用过程中经常需要通过clean up操作来完成本地文件与服务器文件信息及版本信息同步, 然而有时右键会在执行清理命令时提示“清理以下路径失败: xxx 文件名、目录名或卷标语法不…

DevOps 的道术法器,探寻 DevOps “立体化”实践之旅

​引言 随着业务的发展,软件发布迭代的频率越来越高,传统的瀑布型模式已经不能满足快速交付的需求,DevOps 也因此受到持续关注。越来越多的公司开始接受并尝试使用 DevOps,期望能使得软件开发中的构建、测试与发布工作变得更加快捷…

进程与线程的理解

目录 一、进程 1、进程的简介: 2、进程的组成: 3、进程的状态 4、进程控制: 5、进程的创建: 6、进程的终止 7、进程的阻塞和唤醒 8、进程上下文切换 二、线程 1、线程: 2、线程的优缺点: 三、进程与线程 比…

火山引擎 DataLeap:3 步打造“指标管理”体系,幸福里数据中心是这么做的

更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群 一家企业,为什么要搭建指标体系? 一句话总结来说,全面、合理的指标体系可以帮助企业统一目标,将业务环节量化&#…

1073. 负二进制数相加(leetcode,模拟,数学分析)-------------------c++实现

1073. 负二进制数相加(leetcode,模拟,数学分析)-------------------c实现 题目表述 给出基数为 -2 的两个数 arr1 和 arr2,返回两数相加的结果。 数字以 数组形式 给出:数组由若干 0 和 1 组成,按最高有效位到最低有…

Kubernetes1.26.3 高可用集群

Kubernetes1.26.3 高可用集群 0、服务器信息 服务器为腾讯云服务器(按需计费,按流量计费,并且将IP转换为弹性IP,使用结束可关机仅收取硬盘等固定资源费用) 服务器名称IP描述组件信息Kubernetes1124.223.218.159maste…

Matlab如何调用外部函数/工具包,如何将新函数加到默认函数库中

自从开始制作、分享工具包,我被问到最多的一个问题是: “XXX工具包怎么用?” 而我给出的回答通常是: “放在你代码文件夹,当函数调用。” 什么意思呢? 方法1 比如在名为“1”的文件夹中放着我们想要运…

TreeSet源码分析

概述 TreeSet ,基于 TreeSet 的 Set 实现类。在业务中,如果我们有排重 排序的需求,一般会考虑使用 TreeSet #TreeSet的继承关系 TreeSet的内部属性 m 的 key ,存储 HashSet 的每个 key 。 map 的 value ,因为 TreeSe…

DJ5-3 多路访问链路和协议

目录 一、网络链路 二、广播信道要解决问题 三、多路访问协议 1、基本介绍 2、多路访问协议的类型(3) 四、信道划分协议 1、时分多路访问 TDMA 2、频分多路访问 FDMA 3、码分多路访问 CDMA(略) 五、随机访问协议 1、纯…

基于AD96808 FMC 模块,支持8 路14-bit、500MSPS/1GSPS/1.25GSPSADC 采集功能

板卡概述 FMC-XM148 是一款基于VITA57.4 标准的JESD204B 接口FMC 子卡模块,该模块可以实现8 路14-bit、500MSPS/1GSPS/1.25GSPSADC 采集功能。该板卡ADC 器件采用ADI 公司的AD9680 芯片,全功率-3dB 模拟输入带宽可达2GHz。该ADC 与FPGA 的主机接口通过16 通道的高速…

ThingsBoard自定义分发节点duplicate to related

------------------------------------内容仅博主所有,订阅者请勿泄露,感谢--------------------- 1、概述 大家好,我又更新干货了,还是那句话,我绝不像某些博主“拿我格子衫”分享那些照抄官网翻译的东西来骗订阅,我觉得那是浪费时间,要搞就搞干货,今天给大家分享Th…

高端制造业国产化是未来高质量发展的必经之路

在当前全球经济的大背景下,高端制造业已成为各国竞争的焦点。中国作为世界第二大经济体,也在高端制造业领域发挥着越来越重要的作用。然而,我们必须清醒地认识到,目前我国高端制造业的发展还面临着一些困难和挑战,其中…

国产高性能DSP音频处理芯片的工作原理以及应用领域

DSP芯片是数字信号处理器的简称,它是一种专门用于数字信号处理的微处理器,它可以对数字信号进行高速运算和处理。DSP是一类嵌入式通用可编程微处理器,主要用于实现对信号的采集、识别、变换、增强、控制等算法处理,是各类嵌入式系…

ChatGPT 高效对话-学习使用提示语Prompts​

我们整理了一些可以帮助你学习如何使用ChatGPT的资源,包括吴恩达教授最新推出的官方ChatGPT提示词工程师课程的中文B站视频资源,一些插件、使用ChatGPT的标准范式等。 我们将这些所有的相关网址收录到 webhub123 ChatGPT 高效对话-学习使用提示语Promp…