简识MySQL的InnoDB Locking锁的分类

devtools/2025/1/16 7:15:06/

( 参考官方网页: MySQL :: MySQL 5.7 Reference Manual :: 14.7.1 InnoDB Locking)

一、InnoDB Locking锁的分类:

锁的分类英文缩写
共享锁Shared LocksS
排他锁Exclusive LocksX
意向共享锁Intention Shared LocksIS
意向排他锁Intention Exclusive LocksIX
记录锁Record Locks-
间隙锁Gap Locks-
下一键值锁(临键锁)Next-Key Locks-
插入意向锁Insert Intention Locks-
自动插入锁(自增锁)AUTO-INC Locks-

以下是对各类锁的具体说明:

  1. 共享锁(S锁):允许持有共享锁的事务读取一行数据,但不允许修改或删除。在MySQL的InnoDB引擎中,它是行级锁的一种。
  2. 排他锁(X锁):允许持有排他锁的事务更新或删除一行数据,同时阻止其他事务读取、修改或删除该行数据。在MySQL的InnoDB引擎中,它也是行级锁的一种。
  3. 意向共享锁(IS锁):表示一个事务打算在表的单独数据行上设置共享锁。它是表级锁,用于锁定表,以表示稍后将对表中的某些行加共享锁。
  4. 意向排他锁(IX锁):表示一个事务打算在表的单独数据行上设置排他锁。它也是表级锁,用于锁定表,以表示稍后将对表中的某些行加排他锁。
  5. 记录锁:索引记录上的一个锁,锁住单个行记录。在InnoDB中,即使表上没有定义索引,也会创建一个隐式簇索引,并用该索引进行记录锁定。
  6. 间隙锁:索引记录之间间隙上的锁,或第一个索引记录之前或最后一个索引记录之后间隙上的锁。间隙锁是“纯粹禁止的”,它们只是阻止其他事务往指定间隙插入数据,而不阻止不同事务在同一个间隙上获取间隙锁。
  7. 下一键值锁(临键锁):Record Lock和Gap Lock的结合,锁定一个范围,并且锁定记录本身。这种锁在InnoDB中用于防止幻读现象。
  8. 插入意向锁:间隙锁的一种,专门针对insert操作。当多个事务需要向同一个间隙中插入数据时,插入意向锁允许这些事务并行插入,而不会互相阻塞。
  9. 自动插入锁(自增锁):一种特殊的表级别锁,专门针对事务插入AUTO_INCREMENT类型的列。当一个事务正在向表中插入值时,其他事务必须等待,以便第一组事务插入的行接收到连续的主键值。

这些锁机制共同构成了InnoDB强大的并发控制功能,使得MySQL数据库能够在高并发环境下稳定运行。

二、InnoDB中部分锁的举例说明:

1. 共享锁(S锁)

共享锁允许多个事务同时读取同一行数据,但不能修改该数据。

示例

  • 事务1开始,并在id = 1的行上放置共享锁:SELECT * FROM your_table WHERE id = 1 LOCK IN SHARE MODE;
  • 事务2开始,也可以在id = 1的行上放置共享锁并查询:SELECT * FROM your_table WHERE id = 1 LOCK IN SHARE MODE;

在这个例子中,两个事务都可以同时对id = 1的行加共享锁并读取数据。

2. 排他锁(X锁)

排他锁允许事务独占一行数据,其他事务既不能读取也不能修改。

示例

  • 事务1开始,并在id = 2的行上放置排他锁:SELECT * FROM your_table WHERE id = 2 FOR UPDATE;
  • 事务2开始,尝试在同一行查询(会被阻塞,因为有排他锁):SELECT * FROM your_table WHERE id = 2;

在这个例子中,事务1在id = 2的行上放置了排他锁,事务2尝试读取这一行时就会被阻塞,直到事务1提交或回滚。

3. 意向锁(IS锁和IX锁)

意向锁用于表示事务想要在更高级别上获取锁(如表级锁)。意向锁是表级别的锁,不与行级锁冲突。

示例(意向共享锁IS):

  • 事务1开始,先在表上放置意向共享锁,表示想要获取表级共享锁:LOCK TABLE your_table IN SHARE MODE;
  • 事务2开始,尝试直接在表上进行独占操作(会被阻塞,因为有表级的意向共享锁):LOCK TABLE your_table IN EXCLUSIVE MODE;

在这个例子中,事务1先在表上放置了意向共享锁,事务2尝试获取表的排他锁时就会被阻塞。

示例(意向排他锁IX):

  • 事务1开始执行SELECT ... FOR UPDATE语句,此时会对所查询的记录加排他锁,并先对表加意向排他锁。

4. 记录锁

记录锁用于锁定单个行记录。

示例

  • 假设表your_table有字段idname,事务1开始并更新id = 3的行,会在该行上放置记录锁:UPDATE your_table SET name = 'new_name' WHERE id = 3;
  • 事务2开始,尝试更新同一行(会被阻塞,因为有记录锁):UPDATE your_table SET name = 'another_name' WHERE id = 3;

在这个例子中,事务1在id = 3的行上放置了记录锁,事务2尝试更新同一行时就会被阻塞。

5. 间隙锁

间隙锁用于锁定索引记录之间的“间隙”,但不锁定索引记录本身。

示例

  • 假设表your_tableid字段是索引,且有值1、3、5。事务1开始,查询id在1到3之间(不包含1和3)的数据并加锁,会在这个间隙上加间隙锁:SELECT * FROM your_table WHERE id > 1 AND id < 3 FOR UPDATE;
  • 事务2开始,尝试插入id = 2的数据(会被阻塞,因为有间隙锁):INSERT INTO your_table (id, name) VALUES (2, 'new_entry');

在这个例子中,事务1在1和3之间的间隙上加了间隙锁,事务2尝试插入id = 2的数据时就会被阻塞。

6. 下一键值锁(临键锁)

临键锁是记录锁和间隙锁的组合,用于锁定一个索引记录及其前面的间隙。

示例

  • 假设表your_tableid字段是索引,且有值1、3、5。事务1开始,查询id = 3的数据并加锁,会在id = 3的记录及其前面的间隙上加临键锁:SELECT * FROM your_table WHERE id = 3 FOR UPDATE;
  • 事务2开始,尝试插入id = 2的数据(会被阻塞,因为有临键锁锁定了id = 3前面的间隙):INSERT INTO your_table (id, name) VALUES (2, 'new_entry');
  • 事务2尝试更新id = 3的数据(会被阻塞,因为有临键锁锁定了id = 3的记录):UPDATE your_table SET name = 'updated_name' WHERE id = 3;

在这个例子中,事务1在id = 3的记录及其前面的间隙上加了临键锁,事务2尝试插入或更新时都会被阻塞。

7. 插入意向锁

插入意向锁是间隙锁的一种,专门针对insert操作。多个事务在同一个索引、同一个范围区间插入记录时,如果插入的位置不冲突,不会阻塞彼此。

示例(假设与间隙锁示例中的表结构和数据相同):

  • 事务1在1和3之间的间隙上尝试插入id = 2的数据(加插入意向锁)。
  • 事务2也在1和3之间的间隙上尝试插入id = 2.5的数据(加插入意向锁,与事务1不冲突)。

在这个例子中,尽管事务1和事务2都在同一个间隙上尝试插入数据,但由于它们插入的位置不冲突(一个是2,一个是2.5),因此它们可以并行插入而不会互相阻塞。

8. 自动插入锁(自增锁)

自增锁是一种特殊的表级别锁,专门针对事务插入AUTO_INCREMENT类型的列。当一个事务正在向表中插入值时,其他事务必须等待,以便第一组事务插入的行接收到连续的主键值。

示例

  • 假设有数据表t(id AUTO_INCREMENT, name),数据表中有数据:1, shenjian;2, zhangsan;3, lisi。
  • 事务A先执行(还未提交):insert into t(name) values('xxx');会得到一条(4, xxx)的记录。
  • 事务B后执行:insert into t(name) values('ooo');此时需要等待事务A提交后才能继续执行,因为InnoDB在RR隔离级别下使用自增锁来解决幻读问题。

在这个例子中,事务A先执行插入操作并获得了自增锁,因此事务B必须等待事务A提交后才能继续执行插入操作,以确保插入的主键值是连续的。

这些示例展示了InnoDB中各种锁的使用场景和工作方式。在实际应用中,需要根据具体的业务需求和并发控制要求来选择合适的锁类型。

(望各位潘安、各位子健不吝赐教!多多指正!🙏)


http://www.ppmy.cn/devtools/150875.html

相关文章

《鸿蒙Next旅游应用:人工智能赋能个性化与智能导览新体验》

随着鸿蒙Next的推出&#xff0c;旅游应用迎来了全新的发展机遇&#xff0c;借助人工智能技术能为用户带来更出色的个性化推荐和智能导览服务。 鸿蒙Next与人工智能融合优势 鸿蒙Next拥有强大的分布式能力和原生智能体验。其能打破设备界限&#xff0c;实现多设备协同&#xf…

uni-app:动态禁止下拉列表展示情况(如果下拉列表数据为空就拦截下拉框展示,显示提示信息)

效果 如下图&#xff0c;需要当批号的下拉栏位存在数据的时候&#xff0c;才会展示下拉框&#xff0c;现在即使数据为空也会展示下拉框 修改后的效果&#xff0c;只出现提示&#xff0c;不展示下拉框 代码 1、页面展示 设置picker下拉框的外层点击事件&#xff0c;点击事件出…

(STM32笔记)十二、DMA的基础知识与用法 第二部分

我用的是正点的STM32F103来进行学习&#xff0c;板子和教程是野火的指南者。 之后的这个系列笔记开头未标明的话&#xff0c;用的也是这个板子和教程。 DMA的基础知识与用法 二、DMA传输设置1、数据来源与数据去向外设到存储器存储器到外设存储器到存储器 2、每次传输大小3、传…

ubuntu20.04中vscode配置django

1.下载插件 我用的是这两个 2.配置环境 Ubuntu20.04创建虚拟环境 python3 -m venv .venv 没有 venv 的记得装一下 sudo apt install python3.8-venv 装好之后&#xff0c;会出现 .venv 的文件夹 找一下 activate &#xff0c;我的在 bin 里 按照提示 source bin/activate…

嵌入式无人机: 防止信号被有意干扰入侵策略

在嵌入式无人机项目中&#xff0c;防止信号被有意干扰或入侵是一个重要的安全问题。有效的防护措施可以从硬件、软件和通信协议等多个方面入手&#xff0c;确保系统的稳定性和安全性。以下是详细的防护策略&#xff1a; 1. 物理层保护 频率跳变&#xff08;Frequency Hopping…

LeetCode 热题 100 | 普通数组

普通数组基础 动态规划五部曲&#xff1a; 1.确定dp数组的含义 2.递推公式 3.dp数组初始化 4.遍历顺序 5.模拟dp数组合并区间提前排序好数组轮转数组先翻转全部元素&#xff0c;再根据k % nums.length来翻转不同区间。前缀和&#xff0c;后缀和的提前计算。如果想省空间&#x…

funcaptcha手势指向验证码识别

注意&#xff0c;本文只提供学习的思路&#xff0c;严禁违反法律以及破坏信息系统等行为&#xff0c;本文只提供思路 如有侵犯&#xff0c;请联系作者下架 本文滑块识别已同步上线至OCR识别网站&#xff1a; http://yxlocr.nat300.top/ocr/other/21 该验证码会给出某物品所有的…

JAVA多线程学习

文章目录 线程相关概念线程创建继承Thread类Runnable接口多个线程同时操作同一个对象测试&#xff1a;实现callable接口(了解)静态代理lamda表达式 线程状态线程停止线程休眠线程礼让 线程相关概念 线程&#xff1a;是进程的一部分&#xff0c;一个进程之内的线程之间共享进程的…