当前位置: 首页
数据库
MySQL读已提交RC隔离级别减少间隙锁死锁原理

MySQL读已提交RC隔离级别减少间隙锁死锁原理

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

RC隔离级别默认不加间隙锁,只对命中行加记录锁,通过半一致性读减少锁竞争,且执行后立即释放未命中行的锁,降低了死锁概率。RR隔离级别默认加临键锁,扫描范围全加锁并保持到事务结束,死锁风险更高。但RC在唯一键冲突等场景下仍可能隐式加间隙锁。

先直说结论:RC 隔离级别下默认不引入间隙锁,而 RR 则默认启用临键锁。RC 通过半一致性读与早期锁释放机制将死锁概率降至极低,仅锁定实际命中的行;RR 则对扫描范围施加完整锁定,且必须持有至事务结束。两种隔离级别在锁策略上的根本差异,直接导致了死锁发生率的巨大悬殊。 为什么MySQL读已提交(RC)隔离级别能减少间隙锁死锁?

RC 默认不加间隙锁,RR 默认加临键锁

间隙锁(gap lock)是 RR 隔离级别为避免幻读而自动施加的“安全锁”——它不仅锁定匹配的记录,还会锁住索引记录之间的空隙。举例说明:表中存在 id 分别为 1、5、10 的三条记录,当执行 UPDATE t SET name='x' WHERE id BETWEEN 3 AND 8 时,RR 将锁定 (1,5] 与 (5,10) 两个间隙区间,此时其他事务若尝试插入 id=4id=6,则必须等待。而相同语句在 RC 下,仅对实际命中的 id=5 施加一个 record lock,间隙完全开放,任何插入操作均可立即执行。

死锁的产生,多数情况下源于多个事务以不同顺序争夺同一组间隙锁。RC 下根本不涉及跨间隙的锁竞争,因此死锁概率自然大幅降低。

RC 的半一致性读让 UPDATE 不盲目加锁

当 UPDATE 语句扫描到已被其他事务持有 X lock 的记录时,RC 会触发半一致性读(semi-consistent read):首先读取该行最新已提交的版本,判断其是否真正满足 WHERE 条件;仅当条件成立时才尝试加锁。而 RR 则不论条件如何,对扫描到的行直接施加 next-key lock,若锁被占用,则只能阻塞等待。

这一差异意味着什么?

  • 在 RC 下,无索引查询最多只会锁定最终更新的几行
  • 同样的语句在 RR 下可能锁定整个扫描范围(全表扫描 + 全表间隙锁),锁等待链一旦拉长,死锁几乎不可避免

RC 锁释放更早,减少锁持有时间重叠

在 RC 中,UPDATEDELETE 语句执行完毕后,未命中行的锁会立即释放;而 RR 会对所有扫描过的行(包括不满足 WHERE 条件的)都施加 next-key lock,并一直持有到事务提交或回滚。

通过一个例子可以更清晰地理解:执行 UPDATE users SET status=2 WHERE created_at > '2026-01-01' 时,RR 可能锁定几千行(即使实际仅修改了 3 行),导致其他事务无法更新任何一行;而 RC 仅锁定那 3 行,其余扫描行的锁瞬间释放——锁持有窗口越窄,事务间的冲突窗口自然就越小。

RC 下 INSERT 死锁仍可能发生,但诱因完全不同

切勿认为 RC 完全与间隙锁绝缘——在唯一键冲突检查、外键约束校验等场景下,MySQL 仍会施加 gap lock,此时 INSERT 死锁仍有可能出现。但这只是极少数显式约束触发的特殊情况,与 RR 对每个范围查询都默认施加间隙锁的“地毯式覆盖”完全不可同日而语。

因此,真正需要警惕的并非“RC 到底有没有间隙锁”,而是以下两点:

  • 不要在 RC 下想当然地认为“绝对安全”,而忽略了唯一索引冲突时隐式间隙锁的存在
  • 不要因为应用层未能妥善处理不可重复读,就生硬地依靠加锁来硬扛,结果人为制造出新的死锁点

归根结底,间隙锁死锁的减少,本质上是将锁的默认行为从 RR 的保守全覆盖,转向了 RC 的按需最小化——但这一“按需”,最终仍需要你通过正确的 SQL 编写、合理的索引设计以及清晰的业务逻辑才能真正落地生效。

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

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

同类文章
更多
SQL嵌套查询与窗口函数结合使用技巧

SQL嵌套查询与窗口函数结合使用技巧

窗口函数不能直接用于WHERE、GROUPBY或HAVING,需先放入子查询或CTE计算,再在外层引用。典型错误如WHERE中写ROW_NUMBER(),需先用子查询生成编号再过滤。窗口函数排序必须显式写在OVER子句中,CTE比嵌套子查询更可靠。

时间:2026-07-18 18:17
phpMyAdmin导出的Laravel SQL文件生产环境报错原因

phpMyAdmin导出的Laravel SQL文件生产环境报错原因

当使用phpMyAdmin工具导出SQL文件时出现报错,最常见的主要原因包括MySQL版本不匹配(例如8 0特有语法用于5 7)、时区设置语句导致错误、字符集编码不一致等。推荐的解决方法主要包括:注意需要仔细检查文件头部注释内容尤其是版本号,避免使用高版本特有语法,请务必删除SETtime_zone这行语句,并将字符集统一设置为utf8mb4编。

时间:2026-07-18 18:16
MySQL读已提交RC隔离级别减少间隙锁死锁原理

MySQL读已提交RC隔离级别减少间隙锁死锁原理

RC隔离级别默认不加间隙锁,只对命中行加记录锁,通过半一致性读减少锁竞争,且执行后立即释放未命中行的锁,降低了死锁概率。RR隔离级别默认加临键锁,扫描范围全加锁并保持到事务结束,死锁风险更高。但RC在唯一键冲突等场景下仍可能隐式加间隙锁。

时间:2026-07-18 18:16
MySQL批量更新表中特定字段值的方法

MySQL批量更新表中特定字段值的方法

批量更新MySQL表字段,推荐使用CASEWHEN、INSERT…ONDUPLICATEKEYUPDATE或UPDATEJOIN,避免逐行循环。注意语法正确、类型统一,单次更新控制500-1000行,超10万行需分片提交并显式提交事务。

时间:2026-07-18 18:16
phpMyAdmin查询窗口为何无法执行超30秒SQL

phpMyAdmin查询窗口为何无法执行超30秒SQL

phpMyAdmin超时源于$cfg[ ExecTimeLimit ]默认30秒,修改php ini无效,需在config inc php中设为0。MySQL的max_allowed_packet不足也会导致假性超时,需调整配置并重启服务。命令行导入可绕过Web层限制。

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