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

news/2024/5/3 21:32:20/文章来源:https://www.cnblogs.com/yunlongn/p/16630222.html

转载~

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

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

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

  • MVCC能否解决幻读问题

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

1、快照读和当前读

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 ...  # 排他锁
    

2、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不会产生幻读问题。

3、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.luyixian.cn/news_show_2779.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C - Candles

题目链接: C - Candles (atcoder.jp) 题目大意: 给你n个蜡烛的坐标,你想点燃其中k个蜡烛,一开始你在坐标0,每次向左或者向右可以移动一格,问点燃k个蜡烛至少需要移动多少步。 分析: 最优的移动的路线可以看作是一个‘U’型再加上一个线段。 以第一个样例为例: 如图所示…

手机PC安装油猴

一、移动端使用油猴脚本移动端可以不使用油猴插件,就可直接安装脚本(需要浏览器支持),这样天然支持油猴脚本的移动浏览器还是很多,比如:书签地球、X浏览去、M浏览器等,但是各个浏览器的支持情况不一样,下面我以**【书签地球】**为例,展示安装使用,此浏览器经过测试对…

DTSE Tech Talk | 云原生架构下的数字身份治理实践

摘要:由华为技术大咖VS派拉软件CTO为大家详解云原生架构下的身份管理平台,构建云安全数字身份入口。 本文分享自华为云社区《DTSE Tech Talk | 第4期:云原生架构下的数字身份治理实践》,作者: 华为云社区精选。 DTSE Tech Talk是华为云开发者联盟推出的技术公开课,解读云…

【技术流吃瓜】python可视化大屏舆情分析“张天爱“事件网友评论

python可视化大屏分析,舆情分析,张天爱事件目录一、事件背景二、微热点分析二、自开发Python舆情分析2.1 Python爬虫2.2 可视化大屏2.2.1 大标题2.2.2 词云图2.2.3 条形图2.2.4 饼图(玫瑰图)2.2.5 地图三、演示视频 一、事件背景 大家好,我是马哥python说。 演员张天爱于2…

2022-08-26 第六小组 高佳誉 学习笔记

前情提要(博主在复习前端知识,所以近几天没有更新博客。相关前端内容可见博主其他随笔) JQurey 重点事件 与JS的区别 选择器思维导图知识点 1. 定义 JQuery是一个快速、简洁的JavaScript框架,是继Prototype之后又一个优秀的JavaScript代码库(框架)于2006年1月由John Resi…

Shopify Spark主题模板配置修改

对于那些正在启动业务的shopify卖家来说,Spark主题是很好的选择,它跨越了你的愿景和市场之间的差距,将美感和必要性结合在一起,这样你就可以用最小的触角将事情进行下去。通过最少的设置,我们设计了一个主题,以帮助你迅速和毫不费力地开店,同时仍然是一个具有惊人风格的…

NC50940 Running Median

For this problem, you will write a program that reads in a sequence of 32-bit signed integers. After each odd-indexed value is read, output the median (middle value) of the elements received so far.题目原题地址:Running Median 题目编号:NC50940 题目类型:对…

项目工期延后有哪些补救措施?

大部分项目经理都面临过项目延期的情况,特别是在软件开发领域,项目延期情况尤为严重。项目管理者的真正挑战,不是发现问题和记录问题,而是预见问题、控制问题和解决问题。 因此当项目出现了延期状况时,我们需要思考有效的”拯救“之策,尽最大可能将未被终止的项目进行调整…

用于知识图嵌入的多尺度动态卷积网络

原文 Multi-Scale Dynamic Convolutional Network for Knowledge Graph Embedding 出版IEEE Transactions on Knowledge and Data Engineering Volume: 34 Issue: 5 01 May 2022申明 版权归原文作者及出版单位所有,如有侵权请联系删除 摘要 知识图是具有不完全或部分信息的大型…

全同态加密-丁津泰:学习

本文学习丁老师写的同态加密的文章,做些笔记。引言同态加密适用于云计算。 因为任意计算都可以由加法和乘法构成,全同态意味着计算函数\(f\)可以是任意计算操作(任意次加法和乘法)。 同态加密,起源于“隐私同态”的概念,但并未给出具体实现;后续提出一些部分同态性的方案…

打了一场模拟赛的心态,总结

今天打了一场模拟赛总结一下: 题目比较简单(我后面一个题目100一个90都是暴力的功/dogen) Frist problem: 总结:一道伪装成5⭐的打卡题目 用时:2~3min 思路:每输入一个字符串判断最后一个字符就可以得知是哪国的人(因为这几个国结尾字母各不相同) Second problem: 总…

AMBA AHB总结

AMBA AHB(高级高性能总线)介绍 一、AHB简介 AHB是为提出高性能可综合设计的要求而产生的新一代AMBA总线。它是一种支持多总线主机和提供高带宽操作的高性能总线。 AMBA AHB实现了高性能,高时钟频率系统的以下特征要求: 突发传输、分块处理、单周期总线主机移交,单时钟沿操…

[XMAN2018排位赛]AutoKey

1、得到USB流量,首先了解AutoKey是什么 自动秘钥密码(Autokey)_不会学习的小菜鸡的博客-CSDN博客_autokey密码 2、安装UsbKeyboardDataHacker.py 工具 GitHub - WangYihang/UsbKeyboardDataHacker: USB键盘流量包取证工具 , 用于恢复用户的击键信息 3、用UsbKeyboardDataHacke…

Promise的基本用法

一.定义: Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。 二.特点: (1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种…

devexpress 22.1.3 PivotGrid 结合.net6 MVC

效果图 主页面zyjkDetection.cshtml@using Health.Model @using Health.Repository; @*For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 *@ @inject HealthDataContext db @{ViewData["Title"] = …

手绘丛林冒险游戏推荐

mac上的一款手绘丛林冒险游戏《Gibbon: Beyond the Trees》推荐给大家,跟着一只迷路的长臂猿展开冒险旅程,进入未知的危险之地。在解放模式下竞速奔向自由,或者进入长达一小时的叙事故事中,体会世界各地野生动物奋斗求生的真实故事。 软件下载地址 《Gibbon: Beyond the Tr…

springboot实现文件下载(打jar包可下载,可解决下载文件损坏)

前端代码:downloadTemplate(){let url = `${window._CONFIG[domianURL]}/invoice/bmsBillRiskverification/downloadTemplate`;window.location.href = url;}后端代码:/*** @param response* @功能描述 下载文件:*/@RequestMapping("/downloadTemplate")public voi…

python 读取json文件

一个jason文件实例————fcc.json { "organization": "freeCodeCamp", "website": "https://www.freecodecamp.org/", "formed": 2014, "founder": "Quincy Larson", "certifications": [ …

Webpack 4

模块打包工具的由来 Web1.0编写静态页面 表单验证和动效Web2.0 之 AJAX管理数据 和用户进行数据交互大前端开发PC 端 移动端 小程序 APP现代 Web 开发“问题”采用模块化开发 使用新特性提高效率保证安全性 实时监听开发过程使用热更新 项目结果打包压缩优化使用 Webpack 实现项…

使用cmd中的alias来定义别名

作为一枚网络工程师,经常就是面对一堆黑框框,也是就是终端。不同操作系统、不同厂家的目录,功能相同但是键入的命令又大不相同,这些差异化容易让脑子混乱。比如华为、思科、H3C、锐捷的设备,命令都有不同,不过因为系统功能基本上固定的,也没有什么操作空间了,直接记忆即…