其他类型的锁的规则较为简单:
- 间隙锁不和其他锁(不包括插入意向锁)冲突;
- 记录锁和记录锁冲突 , Next-key 锁和 Next-key 锁冲突 , 记录锁和 Next-key 锁冲突;
如下图所示 , 数据库的隔离等级 , SQL 语句和当前数据库数据会共同影响该条 SQL 执行时数据库生成的锁模式 , 锁类型和锁数量 。

文章插图
下面 , 我们会首先讲解一下隔离等级、不同 SQL 语句 和 当前数据库数据对生成锁影响的基本规则 , 然后再依次具体 SQL 的加锁场景 。
隔离等级对加锁的影响MySQL 的隔离等级对加锁有影响 , 所以在分析具体加锁场景时 , 首先要确定当前的隔离等级 。
- 读未提交(Read Uncommitted 后续简称 RU):可以读到未提交的读 , 基本上不会使用该隔离等级 , 所以暂时忽略 。
- 读已提交(Read Committed 后续简称 RC):存在幻读问题 , 对当前读获取的数据加记录锁 。
- 可重复读(Repeatable Read 后续简称 RR):不存在幻读问题 , 对当前读获取的数据加记录锁 , 同时对涉及的范围加间隙锁 , 防止新的数据插入 , 导致幻读 。
- 序列化(Serializable):从 MVCC 并发控制退化到基于锁的并发控制 , 不存在快照读 , 都是当前读 , 并发效率急剧下降 , 不建议使用 。
MySQL 还提供了另一种读取方式叫当前读(Current Read) , 它读的不再是数据的快照版本 , 而是数据的最新版本 , 并会对数据加锁 , 根据语句和加锁的不同 , 又分成三种情况:
- SELECT ... LOCK IN SHARE MODE:加共享(S)锁
- SELECT ... FOR UPDATE:加排他(X)锁
- INSERT / UPDATE / DELETE:加排他(X)锁
不同 SQL 语句对加锁的影响不同的 SQL 语句当然会加不同的锁 , 总结起来主要分为五种情况:
- SELECT ... 语句正常情况下为快照读 , 不加锁;
- SELECT ... LOCK IN SHARE MODE 语句为当前读 , 加 S 锁;
- SELECT ... FOR UPDATE 语句为当前读 , 加 X 锁;
- 常见的 DML 语句(如 INSERT、DELETE、UPDATE)为当前读 , 加 X 锁;
- 常见的 DDL 语句(如 ALTER、CREATE 等)加表级锁 , 且这些语句为隐式提交 , 不能回滚 。
当前数据对加锁的影响SQL 语句执行时数据库中的数据也会对加锁产生影响 。
比如一条最简单的根据主键进行更新的 SQL 语句 , 如果主键存在 , 则只需要对其加记录锁 , 如果不存在 , 则需要在加间隙锁 。
至于其他非唯一性索引更新或者插入时的加锁也都不同程度的受到现存数据的影响 , 后续我们会一一说明 。
具体场景分析具体 SQL 场景分析主要借鉴何登成前辈的《MySQL 加锁处理分析》文章和 aneasystone 的系列文章 , 在他们的基础上进行了总结和整理 。
我们使用下面这张 book 表作为实例 , 其中 id 为主键 , ISBN(书号)为二级唯一索引 , Author(作者)为二级非唯一索引 , score(评分)无索引 。

文章插图
UPDATE 语句加锁分析下面 , 我们先来分析 UPDATE 相关 SQL 在使用较为简单 where 从句情况下加锁情况 。其中的分析原则也适用于 UPDATE,DELETE 和 SELECT ... FOR UPDATE等当前读的语句 。
推荐阅读
- 互动直播中的前端技术——即时通讯
- 茶叶在旅行中的作用,白茶的保健功效介绍
- 富士康|为什么职场中有人错把平台当本事?
- 干粉灭火器的压把怎样才能按下去?
- 底妆怎么画才精致?手把手教会你
- 橘皮红茶是如何制作的?[红茶]
- 敦煌月牙泉其中的水,辨证茶疗与疾病的关系
- 请把风水当回事 好房子好风水的内部布局合理
- 淘宝店铺规划方案 淘宝店铺定价策略
- 人的身材在一天中的什么时候最高?
