当前位置: 首页
数据库
MySQL间隙锁防止幻读原理详解

MySQL间隙锁防止幻读原理详解

热心网友 时间:2026-07-07
转载

直接上结论:Gap Lock(间隙锁)并非在所有场景下都能生效,它对运行环境有着严格的要求——事务隔离级别必须设置为REPEATABLE READ,否则它根本没有“出场”机会。更准确地说,间隙锁从来不会单独存在,而是作为Next-Key Lock(临键锁)的组成部分,专门用来锁定那些“尚未存在的值”,根本目的是防止幻读现象。并且,它仅在范围查询使用了索引时才会真正被激活。

下面将几个关键点逐一拆解,帮助您深入理解MySQL间隙锁的工作机制。

Gap Lock仅在RR隔离级别下生效,RC下完全不触发

这是第一道硬性门槛。换句话说,如果您将隔离级别设为READ COMMITTED,即便执行SELECT * FROM t WHERE id > 10 FOR UPDATE,InnoDB也只会对已存在的行加Record Lock(行锁),不会对行之间的间隙施加任何锁。后果就是:幻读风险完全暴露——其他事务随时可以在id=15的位置插入一条新记录。

因此,在使用间隙锁之前,务必确认当前会话处于REPEATABLE READ隔离级别。检查方法很简单:运行SELECT @@transaction_isolation;,如果返回REPEATABLE-READ,才算满足前提条件。否则,Gap Lock是无法启用的。

Gap Lock从不单独存在,它总是Next-Key Lock的一部分

在InnoDB的锁机制中,您看不到“只加Gap Lock”的操作。间隙锁始终与Record Lock捆绑在一起,共同构成一个完整的Next-Key Lock。举个例子:假设表中有id=5、10、20三行数据,您执行SELECT * FROM t WHERE id > 5 FOR UPDATE,InnoDB实际会加上两个Next-Key Lock:(5,10](锁定记录10以及间隙(5,10))和(10,20](锁定记录20以及间隙(10,20)),并且还会添加一个(20,+supremum]。注意,括号中的开区间才是Gap Lock真正发挥作用的区域——它的职责是阻止其他事务申请Insert Intention Lock(插入意向锁)。要知道,任何插入操作必须先获取该意向锁才能继续,Gap Lock拦截的就是这一步。

这可能听起来有些反直觉,但恰恰是InnoDB的设计哲学:它锁定的是“位置”,而非具体的“值”。

无索引或等值查询时,Gap Lock不会启动

接下来列举几个常见但容易踩坑的场景:

  • WHERE status = 'pending':如果status字段没有建立索引,InnoDB会执行全表扫描,间隙锁根本不会参与。即使有索引,等值查询配合非唯一索引时,仍有可能只加Record Lock,而不覆盖前后间隙。
  • WHERE id > 10(id为主键):这属于典型的走索引范围查询,条件满足,Next-Key Lock会生效,锁定(10,+supremum]整个后缀区间。
  • SELECT * FROM t FOR UPDATE(无WHERE条件):这是最极端的情况——全表扫描时,InnoDB会锁定从(−∞, min_key](max_key, +supremum]的所有间隙,逻辑上相当于锁住了整张表。虽然操作本身允许,但并发性能会急剧下降。

验证Gap Lock是否真正生效,不要只看隔离级别

仅仅执行SET TRANSACTION ISOLATION LEVEL REPEATABLE READ是不够的,必须观察锁的实际行为。最可靠的验证方式是通过performance_schema.data_locks查询:SELECT LOCK_MODE, LOCK_DATA FROM performance_schema.data_locks WHERE LOCK_TRX_ID = '你的事务ID';。如果LOCK_MODE显示为RECORD & GAPRECORD & NEXT-KEY,说明间隙部分已生效;如果只显示RECORD,则仅是行锁;如果根本查不到记录,很可能没有加锁。

还有一种更直观的验证方法:事务A执行SELECT * FROM t WHERE id > 5 FOR UPDATE后,让事务B立刻执行INSERT INTO t VALUES (6, ...)。如果该插入被阻塞,就能确认间隙确实被锁住了。

Gap Lock真正令人头疼的地方在于,它锁定的是“不存在的值”——多个事务对同一段间隙加锁时,彼此之间互不可见。正因如此,一旦插入的顺序不同,就可能引发死锁。更隐蔽的一点是:间隙锁只对当前读(FOR UPDATELOCK IN SHARE MODE)有反应;普通的SELECT走的是MVCC快照读,根本感知不到间隙锁的存在。换句话说,您用快照读查到的数据看起来没问题,但其他事务可能已经悄然在间隙中插入了新记录。

来源:https://www.php.cn/faq/2753390.html

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

同类文章
更多
用Qwen大模型为MySQL查询推荐最佳可视化图表

用Qwen大模型为MySQL查询推荐最佳可视化图表

如何用Qwen大模型为MySQL查询自动推荐最佳可视化图表 你是否希望从MySQL查出的销售数据自动生成柱状图,而不是对着满屏数字发呆?刚写完一条SELECT语句,却不确定该使用折线图还是热力图来展示时间趋势?或者你把查询结果复制进Excel后才想起,其实散点图更能说明问题。这些场景是不是很熟悉?

时间:2026-07-07 07:09
MongoDB 4.0事务处理机制底层原理详解

MongoDB 4.0事务处理机制底层原理详解

MongoDB4 0多文档事务深度复用WiredTiger引擎原生多行事务能力,基于快照隔离和MVCC机制。事务启动获取clusterTime,读操作基于固定快照,写冲突在提交时检测。oplog异步刷盘可能影响持久性,生产环境需启用journal并控制事务超时。

时间:2026-07-07 07:09
Qwen大模型助力MySQL敏感数据脱敏与隐私保护

Qwen大模型助力MySQL敏感数据脱敏与隐私保护

借助Qwen大模型一键生成合规的MySQL脱敏SQL语句 先看一个真实业务场景:你需要在MySQL中对姓名、手机号、身份证号这类敏感字段进行合规脱敏,且脱敏逻辑要具备可复用性、可审计性、可回溯能力。此时直接打开Qwen的Web界面或调用API,输入一条清晰指令就能搞定——例如:“请为MySQL表us

时间:2026-07-07 07:09
数据库里最反直觉的陷阱:NULL不等于空,90%新手踩过坑

数据库里最反直觉的陷阱:NULL不等于空,90%新手踩过坑

NULL是数据库中表示“未知”的特殊标记,而非空值或0。它引入三值逻辑,导致用=NULL查不出数据、COUNT(column)忽略NULL、运算结果全为NULL、NOTIN遇NULL返回空、排序位置因数据库而异。正确处理需用ISNULL判断、COALESCE赋默认值、NOTEXISTS替代NOTIN,建表时尽量设置NOTNULL。

时间:2026-07-07 07:09
Qwen大模型生成MySQL性能优化量化对比报告测评

Qwen大模型生成MySQL性能优化量化对比报告测评

Qwen大模型能够基于两份CSV文件,自动生成一份包含QPS、延迟等8项核心指标的MySQL优化量化对比报告。您只需导出规范的CSV数据,使用特定提示词触发解析,再将结果转为HTML或PDF格式即可交付。此外,通过三步验证流程,可确保所有数据真实可信,满足技术评审要求。需要一份能直接用于技术评审或D

时间:2026-07-07 07:09
热门专题
更多
刀塔传奇破解版无限钻石下载大全 刀塔传奇破解版无限钻石下载大全
洛克王国正式正版手游下载安装大全 洛克王国正式正版手游下载安装大全
思美人手游下载专区 思美人手游下载专区
好玩的阿拉德之怒游戏下载合集 好玩的阿拉德之怒游戏下载合集
不思议迷宫手游下载合集 不思议迷宫手游下载合集
百宝袋汉化组游戏最新合集 百宝袋汉化组游戏最新合集
jsk游戏合集30款游戏大全 jsk游戏合集30款游戏大全
宾果消消消原版下载大全 宾果消消消原版下载大全
  • 日榜
  • 周榜
  • 月榜