【MySQL】幻读被彻底解决了吗?

news2024/12/24 10:57:35

一、MySQL 幻读被彻底解决了吗

MySQL InnoDB 引擎的默认隔离级别虽然是【可重复读】,但是它很大程度上避免幻读现象(并不是完全解决了),解决的方案有两种:

  • 针对快照读(普通 select 语句),是通过 MVCC 方式解决了幻读,因为可重复读隔离级别下,事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的,即使中途有其他事务插入了一条数据,是查询不出来这条数据的,所以就很好的避免了幻读问题。

  • 针对当前读(select ... for update 等语句),是通过 next-key lock(记录锁 + 间隙锁)方式解决了幻读,因为当执行 select ... For update 语句的时候,会加上 next-key lock,如果有其他事务在 next-key lock 锁范围内插入了一条记录,那么这个插入语句就会阻塞,无法成功插入,所以就很好了避免幻读问题。

这次,我会举例两个实验场景来说明 MySQL InnoDB 引擎的可重复读隔离级别发生幻读的问题。

二、什么是幻读?

幻读是数据库中的一种并发问题,指在同一事务中执行两次相同的查询,但第二次查询返回了第一次查询所没有的新数据行。【前后读取的记录数不一致

举个例子:

这是一个电商的大致逻辑,一般用户购买商品后付的钱会先冻结在平台上,然后由平台在固定的时间内结算用户款,例如七天一结算、半月一结算等方式,在结算业务中通常都会涉及到核销处理,也就是将所有为【已签收状态】的订单改为【已核销状态】。

此时假设连接 1 / 事务A 正在执行【半月结算】这个工作,那首先会读取订单表所有状态为【已签收】的订单,并将其更改为【已核销】状态,然后将用户款打给商家。但此时恰巧,某个用户的订单正好到了自动确认收货的时间,因此在事务 A 刚刚改完表中订单的状态时,事务 B 又向表中插入了一条【已签收状态】的订单并提交了,当事务 A 完成打款后,再次查询订单表,结果会发现表中还有一条【已签收状态】的订单数据未结算,这就好像产生了幻觉一样。

发生幻读问题的原因是在于:另外一个事务在第一个事务要处理的目标数据范围之内新增了数据,然后先于第一个事务提交造成的问题。

三、快照图是如何避免幻读的?

可重复读隔离级别是由 MVCC(多版本并发控制)实现的,实现的方式是启动事务后,在执行第一个查询语句后,会创建一个 Read View,后续的查询语句利用这个 Read View,通过这个 Read View 就可以在 undo log 版本链找到事务开始时的数据,所以事务过程中每次查询的数据都是一样的,即使中途有其他事务插入了新记录,也是查询不出来这条数据的,所以就很好的避免了幻读问题。

举个例子:

 

在 MySQL 默认的可重复级别下,有两个事务的执行顺序如下:

从上面查询结果可以看出,即使事务 B 中途插入了一条记录,事务 A 前后两次查询的结果集都是一样的,并没有出现所谓的幻读现象。

四、当前读是如何避免幻读的?

MySQL 里除了普通查询是快照图,其他都是当前读,比如 update、insert、delete,这些语句执行前都会查询最新版本的数据,然后再做进一步的操作。

这很好理解,假设你要 update 一个记录,另一个事务已经 delete 这条记录并且提交事务了,这样不是会产生冲突吗,所以 update 的时候肯定要知道最新的数据。

另外,select ... for update,这种查询语句是当前读,每次执行的时候都是读取最新的数据。

举个例子:

事务 A 执行了这条当前读语句后,就在对表中的记录加上 id 范围 (2,正无穷] 的 next-key lock 间隙锁和记录锁的组合。

然后,事务 B 在执行插入语句的时候,判断到插入的位置被事务 A 加了 next-key lock,于是事务 B 会生成一个插入意向锁,同时进入等待状态,直到事务 A 提交了事务。这就避免了由于事务 B 插入新纪录而导致事务 A 发生幻读的现象。

五、幻读被彻底解决了吗?

可重复读隔离级别下虽然很大程度上避免了幻读,但是还是没有能完全解决幻读

5.1、第一个发生幻读现象的场景:

在可重复读隔离级别下,事务 A 第一次执行普通的 select 语句时生成了一个 ReadView,之后事务 B 向表中新插入了一条 id = 5的记录并提交。接着,事务 A 对 id = 5 这条记录进行了更新操作,在这个时刻,这条新纪录的 trx_id 隐藏列的值就变成了事务 A 的事务 id,之后事务 A 再使用普通 select 语句去查询这条记录时就可以看到这条记录了,于是就发生了幻读。

因为这种特殊场景的存在,在首次查询之后,进行了修改操作使用了当前读,然后再进行查询,得到了当前读的内容,所以我们认为 MySQL Innodb 中的 MVCC 并不能完全避免幻读现象

5.2、第二个发生幻读现象的场景:

  • 事务 A 先执行【快照读语句】:select * from t_test where id > 100 得到了3条记录。

  • 事务 B 插入一个 id = 200 的记录并提交。

  • 事务 A 再执行【当前读语句】: select * from t_test where id > 100 for update 就会得到4条记录,此时也发生了幻读现象。

小结:

MySQK Innodb 引擎的可重复读隔离级别(默认隔离级),根据不同的查询方式,分别提出了避免幻读的方案:

  • 针对快照读(普通 select 语句),是通过 MVCC 方式解决了幻读。

  • 针对当前读(select ... For update 等语句),是通过 next-key lock (记录锁+间隙锁)方式解决了幻读。

所以,MySQL 可重复读隔离级别并没有彻底解决幻读,只是很大程度上避免了幻读现象的发生。

要避免这类特殊场景下发生幻读的现象的话,就是尽量在开启事务之后,马上执行 select ... For update 这类当前读的语句,因为它会对记录加 next-key lock ,从而避免其他事务插入一条新记录。

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

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

相关文章

Element-UI 在表单通过按钮动态增加Tree树形控件

文章目录 问题背景动态增加的Tree控件创建el-tree控件数据动态增加的el-tree控件编辑数据前需进行设置勾选状态新增/编辑请求前需转换格式 问题背景 在表单中动态增加的Tree控件中,注册一个 ref 引用,报错如下: this.$refs[‘showRegionsTre…

Linux下Qt breakpad编译使用

一、下载安装包 下载qbreakpad源码: git clone https://github.com/buzzySmile/qBreakpad.git下载breakpad源码 git clone https://github.com/google/breakpad下载linux-syscall-support 没有这个文件,编译报错 git clone https://github.com/adels…

Stable Diffusion WebUI Ubuntu 22.04 LTS RTX2060 6G 极限显存出图

模型 默认选中 chilloutmix_Ni.safetensors&#xff0c;重启webui.sh进程 正向词 best quality, ultra high res, (photorealistic:1.4), 1girl, <lora:koreanDollLikeness_v15:1> ,<lora:yaeMikoRealistic_yaemikoMixed:1>, 反向词 paintings, sketches, (…

数字万用表的四种妙用方法

数字万用表&#xff08;Digital Multimeter&#xff0c;简称DMM&#xff09;是一种在电子电路测试和维修中常用的仪器。它可以测量电压、电流、电阻等各种电信号参数&#xff0c;同时还可以测试二极管、晶体管等元器件。数字万用表使用数字显示&#xff0c;具有高精度、易读性好…

SQL高级教程第三章

SQL CREATE DATABASE 语句 CREATE DATABASE 语句 CREATE DATABASE 用于创建数据库。 SQL CREATE DATABASE 语法 CREATE DATABASE database_name SQL CREATE DATABASE 实例 现在我们希望创建一个名为 "my_db" 的数据库。 我们使用下面的 CREATE DATABASE 语句&…

SQL19 分组过滤练习题

selectuniversity,round(avg(question_cnt), 3) as avg_question_cnt,round(avg(answer_cnt), 3) as avg_answer_cnt fromuser_profile group byuniversity havingavg_question_cnt < 5or avg_answer_cnt < 20;

抖音矩阵系统源码部署技术分享--基于抖音开放平台

开发概述 开放平台基于开发者诉求和相关平台规则&#xff0c;提供了两种开放模式&#xff1a;能力开放、行业开放。 自研开发者介绍 自研开发者是指有自己的自营业务&#xff0c;或是有多种加盟方的角色&#xff0c;可以基于用户需求&#xff0c;提供完整的技术解决方案。 …

【Redis】高可用之二:哨兵(sentinel)

本文是Redis系列第5篇&#xff0c;前4篇欢迎移步 【Redis】不卡壳的 Redis 学习之路&#xff1a;从十大数据类型开始入手_AQin1012的博客-CSDN博客关于Redis的数据类型&#xff0c;各个文章总有些小不同&#xff0c;我们这里讨论的是Redis 7.0&#xff0c;为确保准确&#xff…

dockerfile常用指令

Dockerfile常用指令 视频学习资料来源这里&#xff0c;点击本行文字即可跳转&#xff0c;讲的比较详细&#xff0c;不过比较老&#xff0c;跟最新的肯定是有一些差异的 Dockerfile官网文档的话点击这里 中文文档可以看看这个&#xff0c;不过没有详细的代码demo 或者是看这个 或…

3. 日志模块(下)

在日志模块的上篇中&#xff0c;我们详细拆解了 MyBatis 是如何整合第三方日志框架&#xff0c;实现了完善的日志功能的。那么在本节中&#xff0c;我们再来具体分析下&#xff1a;为了实现“将日志功能优雅地嵌入到核心流程中&#xff0c;实现无侵入式地日志打印”这一目标&am…

菜谱APP项目实战,可以魔改任意APP——前后端齐全

菜谱APP开发实战&#xff08;可改任意APP&#xff09; 1. 优点 多平台性 由于此APP开发的时候采用的是 uni-app 来开发的&#xff0c;所以说它可以打包成多种形态&#xff0c;在各种平台上进行使用。比如&#xff1a;微信、支付宝等各种小程序。当然也是可以打包成安卓APP&am…

如何学习 Midjourney 绘画,AI绘图

Midjourney 是至今为止最好的 AI 绘图工具&#xff0c;SD还是差了很多。 要用当然用最好的&#xff0c;为了绘制出更符合心意的图&#xff0c;我开始 Midjourney 的学习。 从各种渠道寻找相关的资料&#xff0c;国内国外&#xff0c;或者星球&#xff0c;或者群聊&#xff0c…

简析住宅小区有序充电价格响应的电动汽车有充电策略

安科瑞电气股份有限公司 上海嘉定 201801 摘要&#xff1a;在住宅小区传统建设模式下&#xff0c;充电桩安装难、配套投资大&#xff0c;严重阻碍了充电桩在小区内进行普及使用。为解决该问题&#xff0c;本文首先调研了住宅小区内的电动汽车用户的出行习惯和充电特点&#xf…

SQL力扣练习(六)

目录 1. 部门工资前三高的所有员工(185) 题解一(dense_rank()窗口函数&#xff09; 题解二&#xff08;自定义函数&#xff09; 2.删除重复的电子邮箱(196) 题解一 题解二&#xff08;官方解析&#xff09; 3.上升的温度(197) 解法一&#xff08;DATEDIFF()&#xff09;…

java中地址问题

//第一个大mapMap<String, Object> map new HashMap<>();HashMap<String, String> map2 new HashMap<>();map2.put("358","999");//给小map赋值并将其添加到map中map.put("666",map2);//获取小map并且修改对应的键值对…

商城小程序有哪些优势?

伴随着移动互联网的高速发展&#xff0c;越来越多的实体商家开始转变营销思路&#xff0c;都纷纷开始布局线上市场&#xff0c;尤其是从小程序出现以后。今天新胜天下小编就来和大家聊一聊商城小程序有哪些优势。 1. 拥有众多流量入口 商城小程序本身就是小程序里的一种类型&a…

基于ArcGIS、ENVI、InVEST、FRAGSTATS等多技术融合提升环境、生态、水文、土地、土壤、农业、大气等领域的数据分析能力与项目科研水平研修

【科研团队必选】老师赋予目的不仅仅是技术的掌握&#xff0c;更能从技术融合与科研经验的视角下&#xff0c;培养科研团队科研素质&#xff0c;挖掘-融合-创新 目的&#xff1a;以科研及项目角度解决您的数据分析问题及热点问题&#xff0c;为您的论文写作及项目推进挖掘更好…

技术服务企业缺成本票,所得税高怎么解决?可有良策?

技术服务企业缺成本票&#xff0c;所得税高怎么解决&#xff1f;可有良策&#xff1f; 《税筹顾问》专注于园区招商、企业税务筹划&#xff0c;合理合规助力企业节税&#xff01; 技术服务型企业最核心的价值就是为客户提供技术支撑&#xff0c;而这类型的企业在税务方面面临的…

Observability:Synthetic monitoring - 合成监测入门(二)

在之前的文章 “Observability&#xff1a;Synthetic monitoring - 合成监测入门&#xff08;一&#xff09;” 里&#xff0c;我详细描述了如何使用 Project monitors 来创建监控器。我们可以通过在 terminal 中打入命令&#xff0c;创建最为基本的测试框架文件。我们可以通过…

python scrapy爬取网站数据(二)

用法很简单&#xff0c;先安装Scrapy&#xff0c;我这里是win10环境&#xff0c;py3.10 安装scrapy pip install Scrapy显示如图安装完毕 创建项目 分三步创建 scrapy stratproject spiderdemo #创建spiderdemo 项目&#xff0c;项目名随意取 cd spiderdemo #进入项目目录下…