MySQL间隙锁深入分析

概念

什么是间隙锁?
MySQL的间隙锁(gap lock)是一种锁定相邻数据间隔的机制。

触发时机?
当使用SELECT…FOR UPDATE或UPDATE语句时,MySQL会获取一个范围锁,包括指定条件内的所有数据行,并且还会锁定这些数据行之间的间隔(即间隙)。

目的?
这样可以防止其他事务在这个范围内插入新的数据行,从而保证数据的一致性和完整性,避免幻读

分析

锁定相邻数据间隔?指的是表格数据的相邻?还是索引数据的相邻?
表格数据不一定有序,但索引默认情况下是升序排列的,正常情况下,锁定的应该是一个范围,也就是从小到大的范围,所以所指的应该是索引数据,如果是表格数据,那会出现一些情况,比如数据20的上一条数据是15,下一条数据是10,那锁定的是15-20-10?感觉就很怪是不是,下面我们来实战验证下

实战

创建表

CREATE TABLE `gap_lock_test` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(255) DEFAULT NULL,`age` int(11) DEFAULT NULL,PRIMARY KEY (`id`),KEY `idx_age` (`age`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

准备数据
在这里插入图片描述
给age加了普通索引,主要是为了测试间隙锁,因为普通索引加的才是间隙锁,而主键和唯一索引加的是行锁
idx_age索引结构如下:
在这里插入图片描述

数据在索引中

窗口1:开启事务,update条件age=25的数据,触发间隙锁

mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)mysql> update gap_lock_test set name='forlan' where age=25;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

窗口2:执行insert操作

mysql> insert into gap_lock_test(name,age) VALUES('forlan',25);
2013 - Lost connection to MySQL server during query
mysql> insert into gap_lock_test(name,age) VALUES('forlan',20);
2013 - Lost connection to MySQL server during query
mysql> insert into gap_lock_test(name,age) VALUES('forlan',30);
Query OK, 1 row affected (0.04 sec)
mysql> insert into gap_lock_test(name,age) VALUES('forlan',19);
Query OK, 1 row affected (0.03 sec)

注:上面没返回Query OK,表示被锁住了,等待执行

如果锁的是数据相邻间隔,那么锁住的范围应该是[int最小值,30)
如果锁的是索引数据相邻间隔,那么锁住的范围应该是[20,30)

通过验证,20被锁住了,但19和30都可以执行成功,没有被锁住,所以锁的是索引数据相邻间隔,前闭后开

数据在索引头

窗口1:开启事务,update条件age=20的数据,触发间隙锁

mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)mysql> update gap_lock_test set name='forlan' where age=20;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

窗口2:执行insert操作

mysql> insert into gap_lock_test(name,age) VALUES('forlan',20);
2013 - Lost connection to MySQL server during query
mysql> insert into gap_lock_test(name,age) VALUES('forlan',25);
Query OK, 1 row affected (0.04 sec)
mysql> insert into gap_lock_test(name,age) VALUES('forlan',24);
2013 - Lost connection to MySQL server during query
mysql> insert into gap_lock_test(name,age) VALUES('forlan',0);
2013 - Lost connection to MySQL server during query
mysql> insert into gap_lock_test(name,age) VALUES('forlan',-1);
2013 - Lost connection to MySQL server during query
mysql> insert into gap_lock_test(name,age) VALUES('forlan',-2147483648);
2013 - Lost connection to MySQL server during query
mysql> insert into gap_lock_test(name,age) VALUES('forlan',-2147483649);
1264 - Out of range value for column 'age' at row 1

上面这种就是锁定是数据在索引头,从结果可以看出,从int的最小值-2147483648开始锁住,锁定的范围为[-2147483648,25)
注:MySQL中int的范围为[-2147483648,2147483647]
同理,如果数据在索引尾,那么锁定的范围为[xxx,2147483647)

多个数据

窗口1:开启事务,update范围条件age的数据,触发间隙锁

mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)mysql> update gap_lock_test set name='forlan' where age>=10 and age<=22;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

窗口2:执行insert操作

mysql> insert into gap_lock_test(name,age) VALUES('forlan',10);
2013 - Lost connection to MySQL server during query
mysql> insert into gap_lock_test(name,age) VALUES('forlan',22);
2013 - Lost connection to MySQL server during query
mysql> insert into gap_lock_test(name,age) VALUES('forlan',25);
Query OK, 1 row affected (0.04 sec)
mysql> insert into gap_lock_test(name,age) VALUES('forlan',24);
2013 - Lost connection to MySQL server during query
mysql> insert into gap_lock_test(name,age) VALUES('forlan',9);
2013 - Lost connection to MySQL server during query
mysql> insert into gap_lock_test(name,age) VALUES('forlan',-2147483648);
2013 - Lost connection to MySQL server during query

从结果可以看出,从int的最小值-2147483648开始锁住,锁定的范围为[-2147483648,25)
age>=10 and age<=22,目前最小索引值为20,所以还不满足<=10,所以从int最小值开始锁,满足age<=22的最近索引值为25,所以锁到25,不包括25;

总结,对于这种范围比较,锁住的是这个范围之外,离最近的两个索引值

不确定范围的数据

窗口1:开启事务,update条件in的数据

mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)
mysql> update gap_lock_test set name='forlan' where age in(10,22);
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0  Changed: 0  Warnings: 0

窗口2:执行insert操作

mysql> insert into gap_lock_test(name,age) VALUES('forlan',29);
2013 - Lost connection to MySQL server during query
mysql> insert into gap_lock_test(name,age) VALUES('forlan',100);
2013 - Lost connection to MySQL server during query

对于in多个数,无法识别到具体的范围,所以锁的是全表了

总结

间隙锁,针对查询的条件,可以确定范围的条件,取范围之外离得最近的索引值加锁,锁的范围是[范围左边最近的索引值,范围右边最近的索引值),左闭右开

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

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

相关文章

rhcsa4 进程和SSH

tree命令。用于以树状结构显示目录和文件。通过运行 “tree” 命令可视化地查看文件系统中的目录结构。 tree / systemd是第一个系统进程&#xff08;pid1&#xff09;不启动&#xff0c;其他进程也没法启动&#xff0c; 用pstree查看进程树 我们可以看到所有进程都是syste…

设计模式之模板模式

文章目录 豆浆制作问题模板方法模式基本介绍模板方法模式原理类图对原理类图的说明-即(模板方法模式的角色及职责)模板方法模式解决豆浆制作问题模板方法模式的钩子方法模板方法模式的注意事项和细节 豆浆制作问题 编写制作豆浆的程序&#xff0c;说明如下: 制作豆浆的流程 选…

RocketMQ 消息传递模型

文章目录 0. 前言1. RocketMQ的消息传递模型1.1. 同步发送1.2. 异步发送1.3. 单向发送 2. RocketMQ的批量发送和消费2.1 批量发送2.2 批量消费2.3 Spring Boot集成RocketMQ官方starter 示例 3. 总结4. 参考文档5. 源码地址 0. 前言 RocketMQ 支持6种消息传递方式&#xff0c;我…

pyarmor 加密许可证的使用

一 pyarmor 许可证的用处 文档&#xff1a;5. 许可模式和许可证 — Pyarmor 8.3.6 文档 试用版本有如下的限制&#xff1a; 加密功能对脚本大小有限制&#xff0c;不能加密超过限制的大脚本。 混淆字符串功能在试用版中无法使用。 RFT 加密模式&#xff0c;BCC 加密模式在试…

解决java.io.IOException: Network error

解决java.io.IOException: Network error 解决java.io.IOException: Network error摘要引言正文1. 理解异常的根本原因2. 处理网络连接问题3. 处理连接超时4. 处理协议错误或不匹配5. 异常处理 总结参考资料 博主 默语带您 Go to New World. ✍ 个人主页—— 默语 的博客&#…

24.Xaml ListView控件-----显示数据

1.运行效果 2.运行源码 a.Xaml源码 <Window x:Class="testView.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.mic…

电子信息工程专业课复习知识点总结:(四)信号与系统、数字信号处理

这次我不具体把所有概念写出来了&#xff0c;只针对一些面试中经常提问的重点问题。 第一章 信号与系统基本概念 这里提出一个信号与系统这本书的大纲&#xff1a;这本书研究的就是信号与系统的关系。 一.信号是什么&#xff1f; ①信息是自然世界中一种表现形式&#xff0…

pkg 打包 nodejs

一、先全局安装pkg npm i -g pkg 二、下载打包所需的 node-v16.16.0-linux-x64 和 node-v16.16.0-win-x64 下载地址&#xff0c;里面选择你需要的版本 三、放到pkg的缓存目录 windows&#xff1a;C:\Users\whh\.pkg-cache\v3.4&#xff0c;&#xff08;把whh替换为你的电脑…

用冒泡排序完成库函数qsort的作用

Hello&#xff0c;今天分享的是我们用冒泡函数实现qsort&#xff0c;也就是快排&#xff0c;之前我们也讲过库函数qsort的使用方法&#xff0c;今天我们尝试用冒泡函数实现一下&#xff0c;当然我们也见过qsort&#xff0c;后面也会继续完善的。这几天我是破防大学生&#xff0…

MFC-GetAdaptersAddresses获取网卡信息

需要&#xff1a;#pragma comment(lib, "IPHLPAPI.lib") GetAdaptersAddresses函数参数说明 ULONG bufferSize 0;ULONG result ::GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, nullptr, &bufferSize);/*参数1&#xff1a;ULONG Famil…

【hive】列转行—collect_set()/collect_list()/concat_ws()函数的使用场景

文章目录 一、collect_set()/collect_list()二、实际运用把同一分组的不同行的数据聚合成一个行用下标可以随机取某一个聚合后的中的值用‘|’分隔开使用collect_set()/collect_list()使得全局有序 一、collect_set()/collect_list() 在 Hive 中想实现按某字段分组&#xff0c…

Python数据分析 — 数据分析概念、重要性、流程和常用工具

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。Python数据分析是利用Python编程语言进行数据处理、转换、清洗、可视化和建模的过程。Python在数据科学领域非常流行&#xff0c;有许多强大的库和工具可供使用&#xff0c;例如NumPy、Pandas、Matplotlib和Scikit-learn等…

导数公式及求导法则

目录 基本初等函数的导数公式 求导法则 有理运算法则 复合函数求导法 隐函数求导法 反函数求导法 参数方程求导法 对数求导法 基本初等函数的导数公式 基本初等函数的导数公式包括&#xff1a; C0(x^n)nx^(n-1)(a^x)a^x*lna(e^x)e^x(loga(x))1/(xlna)(lnx)1/x(sinx)cos…

服务器访问本机图片nginx配置

下面是Nginx的配置 然后是yml文件配置 后端返回给前端的数据直接返回这个地址就可以了 {"success": true,"code": "200","msg": "操作成功","data": [{"趋势": "https://120.26.98.185:8090/s…

YOLO物体检测系列3:YOLOV3改进解读

&#x1f388;&#x1f388;&#x1f388;YOLO 系列教程 总目录 YOLOV1整体解读 YOLOV2整体解读 YOLOV3提出论文&#xff1a;《Yolov3: An incremental improvement》 1、YOLOV3改进 这张图讲道理真的过分了&#xff01;&#xff01;&#xff01;我不是针对谁&#xff0c;在…

一点感受

做了两天企业数字化转型的评委&#xff0c;涉及全国最顶级的公司、最顶级的实际落地项目案例&#xff0c;由企业真实的落地团队亲自当面讲解。主要是为了了解了解真实的一线、真实的客户、真实的应用现状和应用水平。 &#xff08;1&#xff09;现状 我评审的涉及底层技术平台&…

JMeter-BeanShell预处理程序和BeanShell后置处理程序的应用

一、什么是BeanShell&#xff1f; BeanShell是用Java写成的,一个小型的、免费的、可以下载的、嵌入式的Java源代码解释器&#xff0c;JMeter性能测试工具也充分接纳了BeanShell解释器&#xff0c;封装成了可配置的BeanShell前置和后置处理器&#xff0c;分别是 BeanShell Pre…

想要精通算法和SQL的成长之路 - 受限条件下可到达节点的数目

想要精通算法和SQL的成长之路 - 受限条件下可到达节点的数目 前言一. 相交链表&#xff08;邻接图和DFS&#xff09; 前言 想要精通算法和SQL的成长之路 - 系列导航 一. 相交链表&#xff08;邻接图和DFS&#xff09; 原题链接 public int reachableNodes(int n, int[][] ed…

Linux下Minio分布式存储安装配置(图文详细)

文章目录 Linux下Minio分布式存储安装配置(图文详细)1 资源准备1.1 创建存储目录1.2 获取Minio Server资源1.3 获取Minio Client资源 2 Minio Server安装配置2.1 切换目录2.2 后台启动2.3 查看进程2.4 控制台测试 3 Minio Client安装配置3.1 切换目录3.2 移动mc脚本3.2 运行mc命…

LeetCode 39. Combination Sum【回溯,剪枝】中等

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…