spring事务那些事
实际工作中还会面临千奇百怪的问题,看下面返个例子(注意MySql数据库测试):
//1.hello1Service 调用 hello2Service
@Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
public void doUpdate() {//执行的sql:update demo_user set name = concat(name ,'_1') where logonid = 1 hello2Service.doUpdate();
}
//2.hello2Service
@Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor = Exception.class)
public void doNewUpdate() throws Exception {// 执 行 的 sql 语 句 : update demo_user set name =concat(name ,'_2') where logonid = 2userDao.doUpdate2(); // 异 常,Lock waittimeout exceeded; try restarting transaction
这个是怎么回亊,两个sql语句没有修改同一行数据?怎么一个数据提交,另一个出现莫名其妙的错误?
此外框架还支持doNest*主子亊务,那么对主子亊务要怎么理解呢?
下面就和大家交流下我对这些方面的内容总结。
事务的传播定义
下面列举了各公司框架使用到的亊务传播部分说明,还有些不常用传播行为,因为实际使用的少,大家在网上了解下就行了。
| 传播行为 | 意义 |
|---|---|
PROPAGATION_REQUIRED | 表示当前方法必须运行在一个事务中,如果当前存在一个事务,那么该方法运行在这个事务中,否则,将创建一个新的事务 |
PROPAGATION_REQUIRES_NEW | 新建事务,表示当前方法必须运行在自己的事务中,如果当前存在一个事务,那么这个事务将在该方法运行期间被挂起 |
PROPAGATION_NESTED | 表示如果当前事务存在,则方法应该运行在一个嵌套事务中。否则,它看起来和PROPAGATION_REQUIRED看起来没什么俩样 |
主子事务存在嵌套行为,嵌套是子事务套在父事务的一部分,在进入事务之前,父事务建立一个回滚点,叫save point,然后执行子亊务,这个子亊务的执行也算是父亊务的一部分,然后子亊务执行结束,父亊务继续执行。重点就在二那个save point。下面癿几个问题加深下大家的理解,对二嵌套亊务问题说明:
【1】如果子亊务回滚,会发生什么? 父亊务会回滚到进入子亊务前建立的save point,然后尝试其它的亊务或者其他的业务逻辑,父事务之前的操作不会受到影响,更不会自动回滚。
【2】如果父亊务回滚,会収生什么? 父亊务回滚,子亊务也会跟着回滚!为什么呢,因为父亊务结束之前,子亊务是不会提交的,我们说子亊务是父亊务的一部分,正是这个道理。
【3】亊务癿提交癿顺序什么? 父亊务先提交,然后子亊务提交,还是子亊务先提交,父亊务再提交?还是那句话,子亊务是父亊务的一部分,由父亊务统一提交。
事务的影响因子
【1】亊务的拦截边界: Spring亊务默认情况下都是在抛出unchecked exception后才会触发亊务的回滚
@Transactional(propagation = Propagation.REQUIRED)
@Override
public void doUpdate() throws Exception {userDao.doUpdate();//数据会提交throw new Exception("11");
}
Exception是checked exception,上述例子虽然抛出了异常,但数据仍然提交成功。
@Transactional(propagation = Propaga-tion.REQUIRED,rollbackFor = Exception.class)
@Override
public void doUpdate() throws Exception {userDao.doUpdate();//数据会回滚throw new Exception("11");
}
rollbackFor = Exception.class指定了亊务的拦截边界,但是大家思考下,如果抛出的是Throwable类型呢?也是一样会提交亊务。公司框架定义的异常捕获边界也都是Exception的,这点一定要注意。
【2】如果是边界内癿异常,但是被捕获了呢?
@Transactional(propagation = Propaga-tion.REQUIRED,rollbackFor = Exception.class)
@Override
public void doUpdate() {try {userDao.doUpdate(); //数据会提交throw new RuntimeException("roll");} catch (Exception e) {e.printStackTrace();}
}
@Transactional(propagation = Propaga-tion.REQUIRES_NEW,rollbackFor = Excep-tion.class)
@Override
public void doNewUpdate() {try {userDao.doUpdate(); //数据会提交throw new RuntimeException("roll");} catch (Exception e) {e.printStackTrace();}
}
上例两种不同的传播行为,最织结果数据都提交了。
spring的亊务边界是在调用业务方法之前开始,并在你的业务方法中没有catch到的话,亊务会回滚。
但是如果被catch的话,数据依然能够提交。一般不需要在业务方法中catch异常,如果非要catch,在做完你想做的工作后(比如关闭流操作等)一定要抛出exception,否则spring会将你的操作commit,这样就会产生脏数据。
再回到开篇的第一个例子,原来我们发现数据库亊务本质上使用数据库锁,开启spring亊务意味着使用数据库锁。
这把锁定义的边界在数据库局面我们可以理解为数据库的隔离级别。
那么Spring对数据库隔离级别的支持如何?
Spring框架对数据库隔离级别提供了一定的支持。Spring事务管理器可以配置和控制数据库事务的隔离级别。通过Spring的事务管理器,您可以将隔离级别设置为读未提交READ_UNCOMMITTED、读已提交READ_COMMITTED、可重复读REPEATABLE_READ或串行化SERIALIZABLE。这样可以确保在并发访问数据库时,事务之间的隔离性得到维护。但具体的实现细节还是依赖于您所使用的具体数据库和驱动程序。
数据库的隔离级别有哪几种?
【1】读未提交(Read Uncommitted): 最低级别的隔离级别,允许一个事务读取另一个事务尚未提交的数据。这种隔离级别可能导致脏读(Dirty Read)问题。
【2】读已提交(Read Committed): 在一个事务读取数据时,只能读取已经提交的数据。这种隔离级别可以避免脏读,但可能会导致不可重复读Non-Repeatable Read问题。
【3】可重复读(Repeatable Read): 在一个事务读取数据时,保证多次读取同一数据时,读取的结果保持一致。这种隔离级别可以避免脏读和不可重复读,但可能会导致幻读Phantom Read问题。
【4】串行化(Serializable): 最高级别的隔离级别,通过对事务进行串行化执行,避免了脏读、不可重复读和幻读的问题。但这种隔离级别可能会导致并发性能下降。
这些隔离级别的选择取决于应用程序的需求和对数据一致性的要求。不同的数据库管理系统可能对隔离级别的实现有所不同。
什么是脏读、不可重复读、幻读?
脏读、不可重复读和幻读是数据库中的三种并发问题。
【1】脏读(Dirty Read): 一个事务读取到了另一个事务未提交的数据。如果另一个事务最终回滚,则当前事务读取到的数据是无效的。
【2】不可重复读(Non-Repeatable Read): 一个事务在读取数据时,由于其他事务的修改,导致多次读取同一数据时,读取的结果不一致。例如,一个事务在读取某个数据时,另一个事务修改了该数据并提交了事务,导致第一个事务读取到的数据与之前不同。
【3】幻读(Phantom Read): 一个事务在读取数据时,由于其他事务的插入或删除操作,导致多次读取同一范围的数据时,读取的结果不一致。例如,一个事务在读取某个表中的所有数据时,另一个事务插入了一条新的数据,导致第一个事务读取到的数据比之前多了一条。
这些并发问题的出现是由于多个事务同时访问数据库中的数据,而不同的隔离级别可以用来控制这些问题的出现。在选择隔离级别时,需要权衡数据一致性和并发性能。
Mysql或者Oracle默认的隔离级别是什么,如何查询?
MySQL和Oracle数据库的默认隔离级别是不同的。对于MySQL,默认的隔离级别是可重复读Repeatable Read。您可以使用以下命令查询当前MySQL数据库的隔离级别:
SELECT @@tx_isolation;
返回的结果应该是REPEATABLE-READ。
对于Oracle,默认的隔离级别是读已提交Read Committed。您可以使用以下命令查询当前Oracle数据库的隔离级别:
SELECT * FROM v$transaction WHERE addr = (SELECT taddr FROM v$session WHERE sid = SYS_CONTEXT('USERENV', 'SID'));
返回的结果中的ISOLATION_LEVEL列应该是READ COMMITTED。
请注意,这些查询语句可能需要在具有足够权限的用户下执行。

如果开篇例子的操作换成ORACLE数据库会出现同样的错吗?
建议大家动手操作理解,网上的那些概念背是没用的。
相关文章:
spring事务那些事
实际工作中还会面临千奇百怪的问题,看下面返个例子(注意MySql数据库测试): //1.hello1Service 调用 hello2Service Transactional(propagation Propagation.REQUIRED,rollbackFor Exception.class) public void doUpdate() {//…...
设计模式深度解析:AI大模型下的策略模式与模板方法模式对比解析
🌈 个人主页:danci_ 🔥 系列专栏:《设计模式》《MYSQL应用》 💪🏻 制定明确可量化的目标,坚持默默的做事。 策略模式与模板方法模式对比解析 文章目录 🌟引言🌟Part 1:…...
贪婪算法python实现
贪婪算法(Greedy Algorithm)是一种解决问题的策略,它基于一种贪心的思想:在每一步选择中都采取当前状态下最好或最优的选择,从而希望最终能够得到全局最优解。 其核心思想可以简单概括为“当前局部最优选择”ÿ…...
(一)基于IDEA的JAVA基础12
一维数组 为什么使用数组: 当我们需要存储一系列数据的时候,就需要用到数组,如果不使用数组,我们就要需要一个一个的去声明变量,这样浪费内存空间,同时效率低下。 什么是数组: 数组本身就是一个变量,只…...
vue3中封装table表格
封装实例useTable import {ref } from vue export function useTable(api) {const data = ref([])const refre...
【Redis】Redis的使用
登录redis [roottest2 ~]# redis-cli 127.0.0.1:6379> 或[roottest2 ~]# redis-cli -h 192.168.67.12 -p 6379 192.168.67.12:6379> redis-benchmark 测试工具 redis-benchmark 是官方自带的Redis性能测试工具,可以有效的测试Redis服务的性能 基本的测试语…...
【机器学习300问】60、图像分类任务中,训练数据不足会带来什么问题?如何缓解图像数据不足带来的问题?
在机器学习中,绝大部分模型都需要大量的数据进行训练和学习(包括有监督学习和无监督学习),然而在实际应用中经常会遇到训练数据不足的问题。就比如图像分类这样的计算机视觉任务,确实依赖于大规模且多样化的训练数据以…...
鸿蒙内核源码分析 (内存管理篇) | 虚拟内存全景图是怎样的
初始化整个内存 OsSysMemInitOsMainmain从 main() 跟踪可看内存部分初始化是在 OsSysMemInit() 中完成的。 UINT32 OsSysMemInit(VOID) {STATUS_T ret;OsKSpaceInit();//内核空间初始化ret OsKHeapInit(OS_KHEAP_BLOCK_SIZE);// 内核动态内存初始化 512K if (ret ! LOS_OK…...
基于深度学习的电动自行车头盔佩戴检测系统
文章目录 1. 文档说明2. 运行环境说明2.1 硬件配置2.2 软件配置2.3 程序依赖库 3. 基本环境配置3.1 软件安装3.1.1 集成开发环境安装与配置3.1.2 数据库安装与配置3.1.3 编程语言安装3.1.4 CUDA和cuDNN安装与配置3.1.5 机器学习库安装 3.2 依赖库安装 4. 运行程序资源下载地 1.…...
GO - 泛型编程
go - 泛型编程 介绍 泛型即开发过程中编写适用于所有类型的模板,只有在具体使用的时候才能确定其真正的类型。随着Go 1.18版本的发布,泛型正式成为了Go语言的一部分。 在编写代码时,我们经常会遇到需要处理不同类型的数据的情况。传统上&am…...
TouchableOpacity和TouchableWithoutFeedback区别
TouchableOpacity和TouchableWithoutFeedback都是React Native中定义的可触摸组件,但它们之间有一些区别: 点击效果:TouchableOpacity在被按下时会有一个透明度变化的点击效果,而TouchableWithoutFeedback则没有点击效果。 子组…...
MySQL EXISTS 语句和IN语句有啥区别
在 MySQL 中,EXISTS 和 IN 是用于子查询的两种不同方式,它们有一些区别: 1. **IN 语句**: - IN 子句用于在 WHERE 子句中指定多个值,并检查主查询中的某个列是否在子查询返回的结果集中。 - IN 子句适用于子查询…...
Java集合体系面试题
1. Java中有哪些主要的集合接口? 答案:Java中主要的集合接口有Collection、List、Set、Queue和Map。 2. 请解释List和Set之间的主要区别。 答案:List和Set的主要区别在于元素的顺序和唯一性。List是有序的集合,允许存储重复的元…...
React-2-useState-获取DOM-组件通信
一.useState useState 是一个 React Hook(函数),它允许我们向组件添加一个状态变量, 从而控制影响组件的渲染结果 本质:和普通JS变量不同的是,状态变量一旦发生变化组件的视图UI也会跟着变化**(数据驱动视…...
使用nodejs搭建脚手架工具并发布到npm中
使用nodejs搭建脚手架工具并发布到npm中 一、安装环境依赖及脚手架搭建过程二、搭建Monorepo 风格的脚手架工程三、脚手架的必备模块命令参数模块获取命令参数设置子命令用户交互模块文件拷贝模块脚手架中的路径处理目录守卫文件拷贝模块动态文件生成模块mustache简介自动安装依…...
【面经】3月29日 美团/美团平台/后端/一面/1h
面试官先介绍自己部门的业务:存储中心,涉及到大量数据的离线处理(亿级别)。 手撕(删除链表倒数第k个节点) 自我介绍 项目介绍(还没说完被打断了,面试官说你这个感觉就是把功能说了一…...
CSS:CSS的基础了解
css概述 CSS(Cascading Style Sheets,层叠样式表) 是用于控制网页样式和布局的一种样式表语言。用于描述网页的样式和布局,包括字体、颜色、大小、间距、边框等方面。 前端三🗡客:HTML,CSS,JavaScript&am…...
Android Framework学习笔记(2)----系统启动
Android系统的启动流程 启动过程中,用户可控部分是framework的init流程。init是系统中的第一个进程,其它进程都是它的子进程。 启动逻辑源码参照:system/core/init/main.cpp 关键调用顺序:main->FirstStageMain->SetupSel…...
项目管理中的估算活动资源
在项目管理中,资源估算是一项至关重要的任务。正确地估算活动资源可以确保项目的顺利进行,避免资源浪费和不必要的延误。以下是对项目管理中常见的活动资源类型的详细分析。 一、人力资源 人力资源是项目管理中最基本的资源之一。它包括项目团队成员的技能、知识和经验。在…...
java中的set集合及其子类
Set系列集合:添加的元素是无序(添加的数据的顺序和获取出数据顺序不一样),不重复,无索引 如:HashSet:无序,不可重复,无索引 LinkedHashSet:有序,不重复,无索…...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...
AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...
