分享好友 最新资讯首页 最新资讯分类 切换频道
Spring隔离级别和数据库隔离级别不一致怎么办
2024-12-30 00:04





上一篇博文介绍了声明式事务@Transactional的简单使用姿势,最文章的最后给出了这个注解的多个属性,本文将着重放在事务隔离级别的知识点上,并通过实例演示不同的事务隔离级别下,脏读、不可重复读、幻读的具体场景

在进入正文之前,先介绍一下事务隔离级别的一些基础知识点,详细内容,推荐参考博文

mysql 之锁与事务[1]

1. 基本概念

以下基本概念源于个人理解之后,通过简单的 case 进行描述,如有问题,欢迎拍砖

更新丢失

简单来讲,两个事务 A,B 分别更新一条记录的 filedA, filedB 字段,其中事务 B 异常,导致回滚,将这条记录的恢复为修改之前的状态,导致事务 A 的修改丢失了,这就是更新丢失

脏读

读取到另外一个事务未提交的修改,所以当另外一个事务是失败导致回滚的时候,这个读取的数据其实是不准确的,这就是脏读

不可重复读

简单来讲,就是一个事务内,多次查询同一个数据,返回的结果居然不一样,这就是不可重复度(重复读取的结果不一样)

幻读

同样是多次查询,但是后面查询时,发现多了或者少了一些记录

比如:查询 id 在[1,10]之间的记录,第一次返回了 1,2,3 三条记录;但是另外一个事务新增了一个 id 为 4 的记录,导致再次查询时,返回了 1,2,3,4 四条记录,第二次查询时多了一条记录,这就是幻读

幻读和不可重复读的主要区别在于:

  • 幻读针对的是查询结果为多个的场景,出现了数据的增加 or 减少
  • 不可重复读对的是某些特定的记录,这些记录的数据与之前不一致

2. 隔离级别

后面测试的数据库为 mysql,引擎为 innodb,对应有四个隔离级别

隔离级别说明fixnot fixRU(read uncommitted)未授权读,读事务允许其他读写事务;未提交写事务禁止其他写事务(读事务 ok)更新丢失脏读,不可重复读,幻读RC(read committed)授权读,读事务允许其他读写事务;未提交写事务,禁止其他读写事务更新丢失,脏读不可重复读,幻读RR(repeatable read)可重复度,读事务禁止其他写事务;未提交写事务,禁止其他读写事务更新丢失,脏读,不可重复度幻读serializable序列化读,所有事务依次执行更新丢失,脏读,不可重复度,幻读-

说明,下面纯为个人观点,不代表权威,谨慎理解和引用

  • 我个人的观点,rr 级别在 mysql 的 innodb 引擎上,配合 mvvc + gap 锁,已经解决了幻读问题
  • 下面这个 case 是幻读问题么?
  • 从锁的角度来看,步骤 1、2 虽然开启事务,但是属于快照读;而 9 属于当前读;他们读取的源不同,应该不算在幻读定义中的同一查询条件中



接下来进入实例演示环节,首先需要准备环境,创建测试项目

创建一个 SpringBoot 项目,版本为2.2.1.RELEASE,使用 mysql 作为目标数据库,存储引擎选择Innodb,事务隔离级别为 RR

1. 项目配置

在项目pom.xml文件中,加上spring-boot-starter-jdbc,会注入一个DataSourceTransactionManager的 bean,提供了事务支持

2. 数据库配置

进入 spring 配置文件application.properties,设置一下 db 相关的信息

3. 数据库

新建一个简单的表结构,用于测试

1. 初始化数据

准备一些用于后续操作的数据

提供一些基本的查询和修改方法

2. RU 隔离级别

我们先来测试 RU 隔离级别,通过指定@Transactional注解的isolation属性来设置事务的隔离级别

通过前面的描述,我们知道 RU 会有脏读问题,接下来设计一个 case,进行演示

事务一,修改数据

只读事务二(设置 readOnly 为 true,则事务为只读)多次读取相同的数据,我们希望在事务二的第一次读取中,能获取到事务一的中间修改结果(所以请注意两个方法中的 sleep 使用)

接下来属于测试的 case,用两个线程来调用只读事务,和读写事务

输出结果如下

关注一下上面结果中ru read only >>>>开头的记录,首先两次输出结果不一致,所以不可重复读问题是存在的

其次,第二次读取的数据与读写事务中的中间结果一致,即读取到了未提交的结果,即为脏读

3. RC 事务隔离级别

rc 隔离级别,可以解决脏读,但是不可重复读问题无法避免,所以我们需要设计一个 case,看一下是否可以读取另外一个事务提交后的结果

在前面的测试 case 上,稍微改一改

测试用例

输出结果如下

从上面的输出中,在只读事务,前面两次查询,结果一致,虽然第二次查询时,读写事务修改了这个记录,但是并没有读取到这个中间记录状态,所以这里没有脏读问题;

当读写事务完毕之后,只读事务的第三次查询中,返回的是读写事务提交之后的结果,导致了不可重复读

4. RR 事务隔离级别

针对 rr,我们主要测试一下不可重复读的解决情况,设计 case 相对简单

我们希望读写事务的执行周期在只读事务的两次查询之内,所有测试代码如下

输出结果

两次只读事务的输出一致,并没有出现上面的不可重复读问题

说明

  • @Transactional注解的默认隔离级别为Isolation#DEFAULT,也就是采用数据源的隔离级别,mysql innodb 引擎默认隔离级别为 RR(所有不额外指定时,相当于 RR)

5. SERIALIZABLE 事务隔离级别

串行事务隔离级别,所有的事务串行执行,实际的业务场景中,我没用过... 也不太能想像,什么场景下需要这种

测试 case

输出结果如下

只读事务的查询输出之后,才输出读写事务的日志,简单来讲就是读写事务中的操作被 delay 了

6. 小结

本文主要介绍了事务的几种隔离级别,已经不同干的隔离级别对应的场景,可能出现的问题;

隔离级别说明

级别fixnot fixRU更新丢失脏读,不可重复读,幻读RC更新丢失 脏读不可重复读,幻读RR更新丢、脏读,不可重复读,幻读-serialze更新丢失、 脏读,不可重复读,幻读-

最新文章
AI�˹�����Ʒ�����а���˹�����δ����չ
�˹����ܣ�AI���ǵ���Ƽ�������Ϊ���ֿ��ȵĻ���֮һ�����ż����IJ��Ͻ�����Ӧ�õ
AutoCMS镜像克隆系统 v5.4 站群版
AutoCMS镜像克隆系统可镜像克隆97%以上网站,小巧快捷方便。1、上传目录中的文件到服务器(请确保支持伪静态)2、后台管理 http://
Android 快影 v5.77.0 去广告去水印解锁会员版
快影app是一款功能强大拍照软件,该软件的亮点功能是辅助构图,构图是一幅好摄影作品的灵魂。快影App构图式拍照相机帮您在拍摄时
AI迎来黄金10年,百度AI技术与应用双剑合璧
编辑 | 于斌出品 | 潮起网「于见专栏」近日,主题为Create 2021的百度AI开发者大会在“希壤”APP召开,这是国内首次在元宇宙中举
AI认知(人类与机器人的对话)
什么是人工智能(Artificial Intelligence)?一个机器人如何拥有智能? 机器人与人类的对话: 机器人:“我想…
Excel怎样排序才能让整个表变动?
如果想要对整个表进行排序,可以使用Excel的排序功能。下面是详细的步骤:1. 选中整个表格。可以在左上角的单元格点击并拖动鼠标
Google搜索流量下降原因分析
有时打开Google Search Console,很不幸会发现网站的 Google 搜索流量下降了。导致自然搜索流量下降的原因有很多,只有了解清楚
Anthropic 联设 1 亿美元 AI 初创基金;OpenAI推出“小”模型GPT-4o Mini;通义千问大模型技术骨干周畅将离职创业丨AI情报局
今日融资快报Anthropic 联手硅谷风险投资公司 Menlo Ventures 设立 1 亿美元 AI 初创基金Menlo Ventures 是 Anthropic 的重要投
4月最值得你体验的端游大作一览,网易《七日世界》开测,韩游《剑星》将正式上线PC
游戏页面》》》》》》《剑星》将于 4 月 26 日正式发售,2 月 7 日开启预购。这款游戏由韩国著名插画师金亨泰担任角色设计,使用
5大硬性要求 送彩票送红包送金币
与往年只设主会场和分会场不同的是,今年双十一还增加了行业分分会场,会场总数高达95个:其中包括1个主会场、20个行业分会场、7