MySQL(九):MVCC能否解决幻读问题

news2024/11/25 2:35:59

尺有所短,寸有所长;不忘初心,方得始终

请关注公众号:星河之码

幻读【前后多次读取,数据总量不一致】

同一个事务里面连续执行两次同样的sql语句,可能导致不同结果的问题,第二次sql语句可能会返回之前不存在的行。

事务A执行多次读取操作过程中,由于在事务提交之前,事务B(insert/delete/update)写入了一些符合事务A的查询条件的记录,导致事务A在之后的查询结果与之前的结果不一致,这种情况称之为幻读

  • MVCC能否解决幻读问题

    首先可以明确的是,MVCC在快照读的情况下可以解决幻读问题,但是在当前读的情况下是不能解决幻读的

一、快照读和当前读

mysql里面实际上有两种读取的方式:快照读和当前读,在之前的文章中《MySQL(八):MVCC多版本并发控制》也有介绍,这里重新简单回顾一下。

  • 快照读【Consistent Read】

    也叫普通读,读取的是记录数据的可见版本,不加锁,不加锁的普通select语句都是快照读,即不加锁的非阻塞读

    快照读的执行方式是生成 ReadView,直接利用 MVCC 机制来进行读取,并不会对记录进行加锁

    如下语句:

    select * from table;
    
  • 当前读

    也称锁定读【Locking Read】,读取的是记录数据的最新版本,并且需要先获取对应记录的锁。如下语句:

    SELECT * FROM student LOCK IN SHARE MODE;  # 共享锁
    SELECT * FROM student FOR UPDATE; # 排他锁
    INSERT INTO student values ...  # 排他锁
    DELETE FROM student WHERE ...  # 排他锁
    UPDATE student SET ...  # 排他锁
    

二、MVCC能解决幻读问题的场景

当我们在读取数据的时候是【快照读】的情况下是可以解决【幻读】的问题,其原理就是MVCC

下面使用案例说明:

假设表中有三条数据,以及有两个事物A/B,A读取数据,B插入数据

#事物A:
select name from user where id > 3;
#事物B:
insert into user valus('6','edwin');

执行过程

时间事务A事物C
1开始事务
2第一次查询:select name from user where id > 3;
6开始事务
7执行插入:insert into user valus(‘6’,‘edwin’);
8提交事务
9第二次查询:select name from user where id > 3;
10提交事务

由于采用的是【快照读】的方式,在A事物开启时会产生一个版本快照,产生版本快照如下

然后通过MVCC的【Read View】对版本快照中各个版本链中的数据进行可见性判断,读取相应的数据版本。两次查询结果都是【id=4,5】两条数据。

Read View具体可见性规则判断在之前的文章中《MySQL(八):MVCC多版本并发控制》有详细的图文详解,这里就不再赘述。

因此,即使事务B新插入了数据,由于已经生成了版本快照,也不会影响Read View的可见性规则判读,所以在【快照读】的情况下,使用MVCC不会产生幻读问题。

三、MVCC不能解决幻读问题的场景

3.1、MVCC什么场景下不能解决幻读问题

当我们在读取数据的时候是【当前读】的情况下,无法使用MVCC解决幻读问题

案例说明:还是先准备几条数据,

有两个事物A/B,A先读取数据,在修改数据,最后有读取数据,B插入数据,看看结果会什么

#事物A:
select name from user where id > 3;
#事物B:
insert into user valus('6','edwin');
#事物A:
update user set name = '彬' where id = 6;

执行过程

时间事务A事物C
1开始事务
2第一次查询:select name from user where id > 3;
6开始事务
7执行插入:insert into user valus (‘6’,‘edwin’);
8提交事务
9第二次查询:select name from user where id > 3;
10修改数据:update user set name = ‘彬’ where id = 6;
11第三次查询:select name from user where id > 3;
12提交事务
  • 在时间点为9的时候

    事务A的【第一次】与【第二次】查询结果与上面的快照读是一样的,基于MVCC两次查询结果都是【id=4,5】两条数据。

  • 在时间点为10的时候

    事务A修改了事务B插入的数据,由于update是当前读,所以此时会读取最新的数据(包括其他已经提交的事务)

  • 在时间点为11的时候

    事务A执行【第三次】查询,是基于当前最新版本查询的,所以会查询到事务B插入的【id=6】的数据,一共会查询到三条数据【id=4,5,6】,与前两次查询结果不同,从而产生了幻读。

3.2、如何解决当前读的幻读问题

在可重复读(RR)的隔离级别下,执行当前读,

案例说明:还是使用上述的数据

  • 事务A,执行当前读,查询id>3的所有记录。
  • 事务B,插入id=5的一条数据。
#事物A:
select name from user where id > 3 lock in share mode;
#事物B:
insert into user valus('6','edwin');

执行过程

时间事务A事物B
1开始事务
2第一次查询:select name from user where id > 3 lock in share mode;
6开始事务
7执行插入时发现,id>3的范围有间隙锁,插入阻塞,处于等待状态
8第二次查询:select name from user where id > 3;
9提交事务
10事物A提交,间隙锁释放,执行插入:insert into user valus (‘6’,‘edwin’);
11提交事务

事务A在执行当前读【select … lock in share mode】的时候,在【id=4,5】的记录上加了共享锁,并且在【id > 6】这个范围上也加了间隙锁,所以上图中的事务B执行插入操作时被阻塞了。所以事务A两次读取的数据是一样的。因此,在这种情况下是不会存在幻读问题。

  • 总结

    RR隔离级别下,当前读执行如下语句时会带上锁之外,还会使用间隙锁+临键锁,锁住索引记录之间的范围,避免范围间插入记录,以避免产生幻影行记录

    SELECT * FROM student LOCK IN SHARE MODE;  # 共享锁
    SELECT * FROM student FOR UPDATE; # 排他锁
    INSERT INTO student values ...  # 排他锁
    DELETE FROM student WHERE ...  # 排他锁
    UPDATE student SET ...  # 排他锁
    
  • 注意

    这种方式不能解决3.1中的幻读问题,因为在3.1中事务A执行修改数据,获取锁之前,已经读取到了事务B插入的数据,并且已经记录到Undo日志中

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

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

相关文章

CSS3动画属性 animation详解(看完就会)

CSS3动画属性 animation 文章包含个人理解错误请指出 往期文章 【css高级】变量详解 轮播图swiper框架的基本使用【Transform3D】转换详解(看完就会)【css动画】移动的小车 【CSS3】 float浮动与position定位常见问题(个人笔记&#xff09…

MySQL入门安装(一步一图)

♥️作者:小刘在C站 ♥️个人主页:小刘主页 ♥️每天分享云计算网络运维课堂笔记,努力不一定有收获,但一定会有收获加油!一起努力,共赴美好人生! ♥️夕阳下,是最美的绽放&#xff0…

三极管工作原理介绍(动画图解)

三极管BJT 各位社区的小伙伴们大家好,相信大家也像我一样,因为上学的时候学过,但是呢,出社会不怎么用,久而久之就忘了,今天来给大家巩固一下,我对三极管的通俗易懂的工作原理介绍! 半…

怎样提高报表呈现的性能

报表的性能很重要,是一个总被谈及的问题,跑的慢的报表用户体验恶劣,无法忍受。解决这些慢的性能问题,也成了项目方和工程师头疼的事情。一出状况,就得安排技术好的,能力强的工程师去救火,本来利…

『赠书活动 | 第二期』《元宇宙Ⅱ:图解元技术区块链、元资产与Web3.0、元人与理想国(全三册)》

💗wei_shuo的个人主页 💫wei_shuo的学习社区 🌐Hello World ! 『赠书活动 | 第二期』 本期书籍:《元宇宙Ⅱ:图解元技术区块链、元资产与Web3.0、元人与理想国》 赠书规则:评论区&…

齐全且实用的MySQL函数使用大全

目录 一、MySQL函数介绍 二、MySQL函数分类 (一)单行函数 ①字符串函数 ②数学函数 ③日期函数 ④流程控制函数 ⑤系统信息函数 ⑥其他函数 (二)聚合函数 三、函数使用示例 (一)字符函数 ①le…

【K8S系列】深入解析etcd

序言 时间永远是旁观者,所有的过程和结果,都需要我们自己去承担。 文章标记颜色说明: 黄色:重要标题红色:用来标记结论绿色:用来标记一级论点蓝色:用来标记二级论点 Kubernetes (k8s) 是一个容器…

WeIdentity智能合约源码分析

WeIdentity智能合约 介绍 本文结合WeIdentity智能合约文档对其源码进行阅读分析。当前,WeIdentity合约层面的工作目标主要包括两部分: WeIdentity DID智能合约,负责链上ID体系建立,具体包括生成DID(Distributed IDe…

【C++】vector类详细总结(包括vector二维数组)(持续更新中)

目录 一、vector的初始化(9种) 二、vector的访问和遍历 2.1 访问(3种) (1)使用下标运算符[]访问和修改 (2)使用迭代器访问 (3)使用at()函数访问 &#…

Spring Boot配置多数据源的四种方式

1、导读 在日常开发中我们都是以单个数据库进行开发,在小型项目中是完全能够满足需求的。 但是,当我们牵扯到像淘宝、京东这样的大型项目的时候,单个数据库就难以承受用户的CRUD操作。 那么此时,我们就需要使用多个数据源进行读写…

centos上使用yum安装redis

使用yum install -y redis时报错,没有找到安装包 解决办法: 下载fedora的epel仓库,yum添加epel源:执行 yum install epel-release 回车 再次:yum install redis 回车 开启redis服务 service redis star…

C语言设计扫雷(保姆级教学)

目录 引入: 游戏思路与逻辑: 游戏具体实现过程 整个程序的大体逻辑: 游戏的执行逻辑: game.h头文件内容: 具体函数讲解 menu(菜单函数) Initboard(初始化棋盘函数&#xff09…

Ubuntu 22.04安装Cuda11.7和cudnn8.6

这篇文章记录了如何在Ubuntu22.04上安装CUDA11.7和cudnn8.6。按照步骤理应可以安装成功。如果还有问题,可以留言。 安装显卡驱动 打开‘软件和更新。 点击附加驱动安装显卡驱动 如果已经安装显卡驱动,请忽略上面的步骤。 安装gcc 新安装的Ubuntu22…

微软 New Bing AI 申请与使用保姆级教程(免魔法)

本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 提问。 大家好,我是小彭。 最近的 AI 技术实在火爆,从 OpenAI 的 ChatGPT,到微软的 New Bing,再到百度的文心一言,说明 AI …

[408] cache与主存的映射部分概念

涉及:基本理解 (防止误解映射规则cache 与 主存 的 "地址"构成主存块、cache块cache容量、cache的总容量有关计算的一些刁难名词不涉及:cache 与 主存映射规则基本理解:  首先我们需要明确的是我们之后针对的位数都是针对的 地址. 与实际的存储的 (01) 二进制无关. …

C# | 对象池

对象池 文章目录 对象池前言什么是对象池对象池的优点对象池的缺点 实现思路示例代码 结束语 前言 当我们开发一个系统或者应用程序时,我们通常需要创建很多的对象,这些对象可能是线程、内存、数据库连接、文件句柄等等。在某些情况下,我们需…

CM311-1A 卡刷 + 线刷、刷安卓与 Armbian 教程

使用到的工具软件与固件下载地址: https://41ws38-my.sharepoint.com/:f:/g/personal/ddf_41ws38_onmicrosoft_com/EhgM458YouBBshliWJhjcDcBAU-F5Mu6HTIU8PeKJHZnZA?eZnJZa6 不能下载,帖子下面评论。 准备工作 设备 / 硬件:CM311-1a YST 电…

C语言格式化输出总结:%d,%c,%s,%f, %lf,%m.nd,%m.nf,%m.ns 以及sprintf函数

凡事发生必将有益于我,高手,从来都不仅仅是具备某种思维的人,而是那些具备良好学习习惯的人,成为高手,无他,手熟尔! -----来自一位IT领域的大神 在最近的学习之中,对于格式化输出这个…

微信小程序图片裁剪功能的实现

文章目录 图片上传与处理图片尺寸适配图片显示与裁剪框裁剪框的拖动与缩放增加canvas并裁剪图片保存图片到相册总结 在之前的博文中,已经介绍了如何使用在前端开发中,实现较方便自由的图片裁剪功能,可见博文: 如何一步步实现图片…

直达CSDN——创作者创收

catalogue 🌟 写在前面🌟 关于创收线下聚会🌟 创作是最简单的变现模式🌟 知识星球是否适合你🌟 独自开-让开发变得简单🌟 税/睡后收入🌟 KOL越具价值🌟 期待创收组织的建立&#x1f…