【MySQL】MySQL间隙锁--幻读解决原理

news2024/11/26 10:46:05

文章目录

  • 一、间隙锁概念
  • 二、测试间隙锁范围加锁
  • 三、测试等值间隙锁

一、间隙锁概念

  • 当我们用范围条件而不是相等条件检索数据, 并请求共享或排他锁时,InnoDB 会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内但并不存在的记录,叫做“间隙(GAP)” ,InnoDB 也会对这个“间隙”加锁,这种锁机制就是所谓的间隙锁
  • 举例来说, 假如 user 表中只有 101 条记录, 其userid 的值分别是 1,2,…,100,101, 下面的 SQL: select * from user where userid > 100 for update;是一个范围条件的检索,InnoDB 不仅会对符合条件的 userid 值为 101 的记录加锁,也会对userid 大 于 101(但是这些记录并不存在)的"间隙"加锁,防止其它事务在表的末尾增加数据
  • InnoDB 使用间隙锁的目的,是为了防止幻读,以满足串行化隔离级别的要求 ,对于上面的例子,要是不使用间隙锁,如果其他事务插入了 userid 大于 100 的任何记录,那么本事务如果再次执行上述语句,就会发生幻读

InnoDB串行化隔离级别使用间隙锁(gap lock)解决幻读(事务并发情况下两次查询的数据量不同)问题

间隙锁专用于串行化隔离级别,可解决幻读问题,幻读问题表现为:当前事务没做操作,前后两次相同的查询语句,显示的数据量不一致
在这里插入图片描述

我们把事务2 select的指定的条件分为2类:范围查询、等值查询

record lock:记录锁,就是行锁
gap lock:间隙锁,不包含记录本身
next-key lock:record lock(记录本身) + gap lock(不包括记录本身)

二、测试间隙锁范围加锁

设置事务为手动提交,然后把隔离级别设置成串行化
在这里插入图片描述

查看表结构,id、age、name都有索引
在这里插入图片描述

场景1:用不可重复的主键id测试间隙锁
范围查询
在这里插入图片描述

事务2的select操作只给三行数据加了共享锁,为什么插入id为24的数据也不行呢?

这是因为在串行化隔离级别中,不仅仅是获取了满足条件的这3行的行锁,而且把表记录之间以及后边空洞的地方也加上了间隙锁
在这里插入图片描述

图中红色线的地方都上了next-key锁,上锁范围(左开右闭)为:( 11 , 12 ] ∪ ( 12 , 22 ] ∪ ( 22 , 23 ] ∪ ( 23 , + ∞ ] (11,12]\cup(12,22]\cup(22,23]\cup(23,+\infty](11,12]∪(12,22]∪(22,23]∪(23,+∞]

上述select不仅仅获取了12,22,23的共享行锁(record-lock),还把间隙加了间隙锁,其实就是给间隙加上共享锁或者排他锁,由于我们这里是select,所以是给间隙加上了共享锁(我们select id>11还是可以的,不能update、insert、delete id>11的数据)

也就是说,我们可以在id小于11的地方update/delete,加排它锁。但是操作了id<=11的部分,不影响相同的select * from stu where id>11所获取的数据量,这样就能防止幻读发生

串行化隔离级别通过给select的部分加间隙锁,防止其他事务在加了间隙锁的区间进行增加或删除数据,就能防止幻读

场景2:用可重复的age(有索引)测试间隙锁
测试辅助索引树上,间隙锁的范围

我们先查看一下表结构、表数据,然后回滚
在这里插入图片描述

开启事务进行测试
在这里插入图片描述

很明显,由于age>20的区间都被事务1加上了间隙锁(这里加的是共享锁),所以事务2插入age=22和age=21都失败了

在这里插入图片描述

幻读就是同一事务两次用相同的条件查询数据,下一次查出的数据量和上一次的数据量不一样,就算事务1把age=20的数据插入表,事务2再用age>20查询,得到的数据量也不会改变。

那事务1插入age=20的数据能否成功呢?

在这里插入图片描述

依然不能成功,这是因为我们插入的数据id是自增的,所以这条数据(age=20,id=24),位于辅助索引树中(age=20,id=12)的右边,由于(age=20,id=12)右边都被上了锁,(age=20,id=24)自然无法插入

也就是说,如果我们指定age=20,id合法且<12,则可插入

在这里插入图片描述

很显然,事务1插入的age=18和age=19都不在事务2上锁的范围,所以可以插入

如果只是在辅助索引树上查找,不回表,那么主键索引树上不会加锁

在这里插入图片描述
在这里插入图片描述

select id from stu where age>14后,辅助索引树加锁区间如下:

在这里插入图片描述

在这里插入图片描述

场景3:实际情况需要具体分析用的到底是行锁还是表锁
在这里插入图片描述

回滚,重新开启事务
在这里插入图片描述

开始测试
在这里插入图片描述

我们发现事务1无论是插入age>18范围内的数据,还是范围外的数据,都无法成功

这时我们就要分析了,这应该没有用到索引,因为我们用索引,过滤出的数据占了整张表的一大半,MySQL server没使用索引。

没有加行锁,只能加表锁(这时加的是共享锁),所以事务1无论插入什么数据都不行
在这里插入图片描述

果然,没有用到索引
在这里插入图片描述

age>20用到了索引,所以可以用行锁

三、测试等值间隙锁

查看表结构和表数据
在这里插入图片描述

设置成手动提交,设置串行化隔离级别。回滚,然后启动事务
在这里插入图片描述

  1. 测试不能重复的主键索引
    此时事务2 select,由于是等值查询,相当于给这条数据加上了共享锁

在这里插入图片描述

事务1现在插入新的数据是可以成功的,因为主键id不能重复,我们不能再插入主键id=9的数据
在这里插入图片描述

在这种情况下,由于id=9的数据已经存在,主键和唯一键是不能重复的,事务2进行等值查询时,事务1插入一个新的数据,不用担心这条新插入的数据和查询条件是一样的,如果主键一样,SQL语句执行失败,所以肯定能成功

  1. 测试能重复的辅助索引
    回滚并重启事务
    在这里插入图片描述

事务2等值查询,给age=18这行数据加上共享锁(record-lock)

在这里插入图片描述
在这里插入图片描述

事务1插入age=18,这是不能允许的,否则事务2再查询age=18就有两条记录了(幻读)
在这里插入图片描述

奇怪的是,我们插入age=17、16、15都被阻塞了,而14、13成功了
在这里插入图片描述

这是因为,为了防止幻读,除了age=18这条数据加了共享锁,其两侧也被加上了间隙锁,因为在这种情况下,插入(age=18,id=10)和(age=18,id=8)是会发生幻读的,所以在一切会影响select * from user where age=18查询结果的地方都加上了间隙锁,但这也会导致一些本不影响查询结果的语句也执行失败,比如插入(age=17,id=24)虽然不影响上述SQL执行结果,由于在间隙锁范围内,依然无法插入

如果插入(age=15,id=1)就可以成功,根据辅助索引值相同,按照主键值升序排列,(age=15,id=1)应该放在(age=15,id=23)前面,不在间隙锁范围内

在这里插入图片描述

间隙锁是给不存在的数据记录的范围加锁:

  • 对于辅助索引,若值允许重复,在串行隔离级别中如果进行等值查询,InnoDB会给数据加上record-lock和gap-lock(防止别的事务插入索引值重复的数据,造成幻读)
  • 对于主键索引,或者唯一键索引,值不允许重复,那只需要加行锁就够了,不需要再加间隙锁(对于唯一键索引,不可能发生插入索引值重复的数据)

串行化隔离级别通过排它锁和共享锁解决脏读、不可重复读(两次查询的数据内容不同),通过间隙锁解决幻读(两次查询的数据量不同)

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

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

相关文章

八、视图集ModelViewSet(重点)

上一章&#xff1a; 七、Django DRF框架GenericAPIView--搜索&排序&分页&返回值_做测试的喵酱的博客-CSDN博客 下一章&#xff1a; 九、DRF生成API文档_做测试的喵酱的博客-CSDN博客 一、视图集ModelViewSet与ReadOnlyViesSet ModelViewSet视图集 与 ReadOnly…

第13届蓝桥杯Scratch国赛真题集锦

编程题 第 1 题 问答题 LED屏幕 题目说明 编程实现 LED屏幕 具体要求: 1).点击绿旗,在舞台中心区域出现由10 x 10方格组成的LED屏幕; 2).按下空格键,LED屏幕最外环方格全部点亮 (方格变为黄色) 3).LED屏幕每秒向内点亮一层,其它LED灯熄灭; 4).直到LED灯在最中心点亮2秒…

games101作业5

作业要求 • Renderer.cpp 中的 Render()&#xff1a;这里你需要为每个像素生成一条对应的光 线&#xff0c;然后调用函数 castRay() 来得到颜色&#xff0c;最后将颜色存储在帧缓冲区的相 应像素中。 • Triangle.hpp 中的 rayTriangleIntersect(): v0, v1, v2 是三角形的三个…

字节跳动测开岗面试居然这么简单....

因为读者里有不少刚入门测试的同学&#xff0c;这两天抽空整理了一份字节测开实习的面试题答案&#xff0c;说实话这个题目真挺简单的&#xff0c;如果你面大厂碰到此类面试题&#xff0c;也算是运气很好啦。大家也可以先自测一下&#xff0c;看看自己能不能答上来。 如果觉得…

vscode 插件 remote-ssh的安装及使用

文章目录 vscode 插件 remote-ssh的安装及使用windows VSCode(clangdremote-ssh) linux(clangd server) 开发环境问题问题1 : getPlatformForHost was canceled问题2 : host 主机不能联互联网问题3 : 每次都要输入密码 vscode 插件 remote-ssh的安装及使用 需要用到的东西1. r…

安装nodejs环境搭建vue项目的框架

说明&#xff1a;想要搭建一个vue项目的框架&#xff0c;先要安装nodejs环境&#xff1b;我的电脑已经安装过&#xff0c;先卸载掉&#xff0c;重新装一遍&#xff08;卸载nodejs参考&#xff1a;http://t.csdn.cn/jHmCU&#xff09; 一、安装nodejs环境 第一步&#xff1a;下…

ssh无密码链接

ssh的基本语法为 ssh host 然后输入密码才可以 如果a想要免密登录b&#xff0c;则a需要将自己的公钥放在b上&#xff0c;原理如下图&#xff1a; 例如&#xff0c;以aricoder这个用户登录的情况下&#xff0c;在服务器01上生成密钥&#xff0c;命令为 ssh-keygen -t rsa然后连…

前端面试题汇总大全二(含答案超详细,Vue,TypeScript,React,Webpack 汇总篇)-- 持续更新

前端面试题汇总大全&#xff08;含答案超详细&#xff0c;HTML,JS,CSS汇总篇&#xff09;-- 持续更新 前端面试题汇总二 五、Vue 篇1. 谈谈你对MVVM开发模式的理解&#xff1f;2. v-if 和 v-show 有什么区别&#xff1f;3. r o u t e 和 route和 route和router区别4.vue自定义…

千万级oracle数据表定时同步到mysql表的方案

1&#xff1a;业务背景 第三方系统提供了一张oracle视图&#xff0c;该视图有六千多万条数据&#xff0c;后续每月会产生三百万条数据的数据。需要每天将数据定时同步到自己系统的mysql表中。 &#xff08;注&#xff1a;我们系统与外界系统访问都要经过一个中间系统的跳转才…

看我0~1精通自动化测试实战,暴涨18K...

前言 开头&#xff0c;先说一下现主流的接口自动化测试框架配套&#xff0c;也是很多企业在使用的。 接口自动化测试&#xff1a;PythonrequestspytestyamlalluerJenkins&#xff1b; Python自动化测试&#xff1a;7天练完这60个实战项目&#xff0c;年薪过35w。 除开测试脚本…

基于秒杀-----分布式锁----lua脚本

基于商品显示秒杀-一人一单业务_xzm_的博客-CSDN博客改进 分布式锁&#xff1a;满足分布式系统或集群模式下多进程可见并且互斥的锁 分布式锁的五个基本要求&#xff1a;多进程可见&#xff0c;互斥&#xff0c;高可用&#xff0c;高性能&#xff0c;安全性 三种实现方式 redi…

《斯坦福数据挖掘教程·第三版》读书笔记(英文版) Chapter 9 Recommendation Systems

来源&#xff1a;《斯坦福数据挖掘教程第三版》对应的公开英文书和PPT Chapter 9 Recommendation SystemsRecommendation systems use a number of different technologies. We can classify these systems into two broad groups. Content-based systems examine properties…

STL 函数对象,即仿函数

目录 1.函数对象 1.1函数对象的概念 1.2函数对象的使用 2.谓词 2.1谓词概念 2.2一元谓词 2.3二元谓词 3.内建函数对象 3.1内建函数对象的意义 3.2算术仿函数 3.3关系仿函数 3.4逻辑仿函数 1.函数对象 1.1函数对象的概念 1.2函数对象的使用 #include<iostream>…

文心一言 VS 讯飞星火 VS chatgpt (25)-- 算法导论4.2 7题

七、设计算法&#xff0c;仅使用三次实数乘法即可完成复数 abi和cdi 相乘。算法需接收a、b、c和d 为输入&#xff0c;分别生成实部 ac-bd 和虚部adbc。 文心一言&#xff1a; 可以使用如下算法来计算复数 abi 和 cdi 的积&#xff0c;且只需进行三次实数乘法&#xff1a; 1.…

Slower使用教程完整版本【2023年更新】

Slower软件的版本&#xff0c;目前市面上有多种。 如果你指的是Slower器加速软件的话&#xff0c;可以看下面的教程&#xff1a; Slower是一款很不错的安全国际互联网工具&#xff0c;广泛用于外贸与留学生行业&#xff0c;设计师行业与科研行业。但是&#xff0c;因为使用过…

注意:腾讯云轻量应用服务器十大限制说明

腾讯云轻量应用服务器相对于云服务器CVM是有一些限制的&#xff0c;比如轻量服务器不支持更换内网IP地址&#xff0c;不支持自定义私有网络VPC&#xff0c;内网连通性方面也有限制&#xff0c;轻量不支持CPU内存、带宽或系统盘单独升级&#xff0c;只能整个套餐整体升级&#x…

IO系统(计算机组成原理)

IO系统这一章主要讲的就是IO的四种控制方式&#xff0c;首先对这四种方式进行一个简单介绍&#xff0c;下面再对着四种方式分别进行介绍。 程序查询方式&#xff1a;由cpu通过程序不断查询IO设备是否已经做好准备&#xff0c;从而控制IO设备于主机进行信息交换 程序中断方式&am…

python自动化测试面试题,25K入职字节测试岗

问&#xff1a; http 和 https的区别   答&#xff1a; https需要申请ssl证书&#xff0c;https是超文本传输协议&#xff0c;信息是明文传输&#xff0c;https则是具有安全性的ssl加密传输协议http和https使用的是不同的链接方式&#xff0c;用的端口也不一样&#xff0c;前…

《深入理解计算机系统》读书笔记1

1.1信息就是位上下文 只由ASCLL字符构成的文件称为文本文件&#xff0c;所有其他文件都称为二进制文件。 系统中的所有的信息都由一串比特表示。区分不同数据对象的唯一方法是读到这些数据对象时的上下文。 1.2程序被其他程序翻译成不同的格式 预编译&#xff0c;编译&#xf…

【C++】类的访问权限

欢迎来到博主 Apeiron 的博客&#xff0c;祝您旅程愉快 &#xff01;时止则止&#xff0c;时行则行。动静不失其时&#xff0c;其道光明。 目录 1、缘起 2、示例代码 3、总结 1、缘起 在 C 中&#xff0c;类在设计时&#xff0c;可以把 属性 和 行为 放在不同的权限下加以…