MySQL间隙锁深入分析

news2024/11/30 6:41:04

概念

什么是间隙锁?
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.coloradmin.cn/o/1007885.html

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

相关文章

离散数学 学习 之 一阶逻辑基本概念 (一 )

个体词可以 理解为主语 &#xff0c; 3 不是偶数 &#xff0c;3 就是 个体常项 凡整数都能被 2 整除 &#xff0c; 整数就是 个体变项 上面的谓词是 &#xff08; 1 &#xff09; 是无理数 &#xff08; 2 &#xff09; 是有理数 &#xff08; 3 &#xff09; 与 同岁 &#xf…

四川百幕晟科技:提升店铺质量方法是什么?

抖店是抖音旗下的移动电子商务平台&#xff0c;为商家提供在线销售和促销的机会。在抖店&#xff0c;经验值是商家评价和信誉的重要指标之一。反映了平台上商户的服务质量和用户满意度。那么&#xff0c;如何查看自己在抖店手机上的体验分数呢&#xff1f; 1、如何查看抖店手机…

C# 随机数生成 Mersenne Twister 马特赛特旋转演算法 梅森旋转算法

NuGet安装MathNet.Numerics 引用: using MathNet.Numerics.Random; /// <summary>/// 包括lower&#xff0c;不包括upper/// </summary>/// <param name"lower"></param>/// <param name"upper"></param>/// <para…

老师如何私发成绩?

尊敬的各位老师&#xff0c;大家好&#xff01;你是否曾经为繁琐的成绩管理和与学生家长的沟通而感到头疼&#xff1f;是否希望有一个简单方便的工具&#xff0c;能够帮助你私发成绩、管理班级和与家长交流&#xff1f;那么&#xff0c;易查分将是你的最佳选择&#xff01;易查…

destoon根据标题删除重复数据

因为采集数据比较庞大&#xff0c;难免出现重复数据&#xff0c;所以写了一个根据标题进行删除重复数据的mysql命令&#xff0c;需要的朋友可以使用。 DELETE from destoon_article_36 where title in (SELECT * from (SELECT title FROM destoon_article_36 GROUP BY title …

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

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

超强干货,Pytest自动化测试框架fixture固件使用,0-1精通实战

前言 如果有以下场景&#xff1a;用例 1 需要先登录&#xff0c;用例 2 不需要登录&#xff0c;用例 3 需要先登录。很显然无法用 setup 和 teardown 来实现了 fixture 可以让我们自定义测试用例的前置条件 fixture 的优势 命名方式灵活&#xff0c;不局限于 setup 和teard…

黑马JVM总结(七)

&#xff08;1&#xff09;StringTable_编译器优化 “a”“b”对应#4&#xff1a;是去常量池中找ab的这个符号 astore 5&#xff1a;是把这个存入编号为5的局部变量 “ab”对应的指令 #4&#xff0c;跟“a”“b”对应#4下面弄是一样的 在执行s3“ab”这行个代码时&#xf…

【Python】从入门到上头—mysql数据库操作模块mysql-connector和PyMySQL应用场景 (15)

mysql-connector MySQL官方提供了mysql-connector-python驱动 安装驱动 python -m pip install mysql-connector连接数据库获取连接 import mysql.connectordb mysql.connector.connect(host"localhost", #ipuser"root", #用户名passwd"root",…

Python的命令行参数

Python的命令行参数&#xff0c;提供了很多有用的功能&#xff0c;可以方便调试和运行&#xff0c;通过man python就能查看&#xff0c;以下是一些常用参数使用实例和场景: 1. -B参数 在import时候&#xff0c;不产生pyc或者pyo文件: 比如有程序main.py如下: from Hello im…

SSM - Springboot - MyBatis-Plus 全栈体系(七)

第二章 SpringFramework 四、SpringIoC 实践和应用 3. 基于 注解 方式管理 Bean 3.4 实验四&#xff1a;Bean 属性赋值&#xff1a;基本类型属性赋值&#xff08;DI&#xff09; Value 通常用于注入外部化属性 3.4.1 声明外部配置 application.properties catalog.nameM…

UG\NX二次开发 获取装配部件的相关信息UF_ASSEM_ask_component_data

文章作者:里海 来源网站:王牌飞行员_里海_里海NX二次开发3000例,里海BlockUI专栏,C\C++-CSDN博客 简介: UG\NX二次开发 获取装配部件的相关信息UF_ASSEM_ask_component_data 包括:零件名称、引用集名称、实例名称、组件的位置、坐标系矩阵、转换矩阵。 效果: 代…

Docker基础学习

Docker 学习目标&#xff1a; 掌握Docker基础知识&#xff0c;能够理解Docker镜像与容器的概念 完成Docker安装与启动 掌握Docker镜像与容器相关命令 掌握Tomcat Nginx 等软件的常用应用的安装 掌握docker迁移与备份相关命令 能够运用Dockerfile编写创建容器的脚本 能够…

并联电容器交流耐压试验方法

对被试并联电容器两极进行充分放电。 检查电容器外观、 污秽等情况, 判断电容器是否满足试验要求状态。 用端接线将并联电容器两极短接连接湖北众拓高试工频耐压装置高压端, 外壳接地。 接线完成后经检查确认无误, 人员退出试验范围。 接入符合测试设备的工作电源&#xff0c;…

Java(二)--面向对象

十.封装 1.访问权限不用加 在c中是访问权限&#xff1a; 属性/行为&#xff1a; class Person{public:void speak(){cout<<"666";} }; 在Java中是访问权限 属性/行为&#xff1a; class Person{public void speak(){cout<<"666";} }; 2.…

管理类联考——数学——汇总篇——知识点突破——代数——数列

⛲️ 一、考点讲解 1.数列的定义 按一定次序排列的一列数称为数列。 一般形式&#xff1a; a 1 &#xff0c; a 2 &#xff0c; a 3 &#xff0c; … &#xff0c; a n &#xff0c; … &#xff0c; a_1&#xff0c;a_2&#xff0c;a_3&#xff0c;…&#xff0c;a_n&#xf…

ICCV 2023 | 沉浸式体验3D室内设计装修,基于三维布局可控生成最新技术

文章链接&#xff1a; https://arxiv.org/abs/2307.09621 360场景布局可控合成&#xff08;360-degree Image Synthesis&#xff09;目前已成为三维计算机视觉领域一个非常有趣的研究方向&#xff0c;在虚拟三维空间中沉浸式的调整和摆放场景对象&#xff0c;可以为用户带来身临…

线性代数的本质(八)——内积空间

文章目录 内积空间内积空间正交矩阵与正交变换正交投影施密特正交化实对称矩阵的对角化 内积空间 内积空间 三维几何空间是线性空间的一个重要例子&#xff0c;如果分析一下三维几何空间&#xff0c;我们就会发现它还具有一般线性空间不具备的重要性质&#xff1a;三维几何空…

Java项目-苍穹外卖-Day12-Apache POI及Excel数据报表

文章目录 前言工作台需求分析代码导入功能测试 Apache POI介绍入门案例写入excel文件内容读取excel文件 导出运营数据Excel表需求分析代码开发功能测试 前言 最后一天&#xff0c;主要就是数据怎么从后端导出到excel表格&#xff0c;以及工作台内容的开发 工作台 需求分析 代…

中秋国庆双节邮件营销怎么做?看这里!

今年的国庆节恰逢中秋节&#xff0c;因此国家假日办安排国庆中秋连放8天。对于打工人来说&#xff0c;超长的假期是外出旅游、回家探亲好时机&#xff0c;可是对于企业来说&#xff0c;却是一次仅次于春节的营销大战。这个时候企业营销人员当然是要借助各种营销手段来获取流量和…