2026-04-21 20:58:45
MySQL 的锁主要分为表锁和行锁两大类,其加锁原理与存储引擎、隔离级别及索引使用方式密切相关。以下是详细分类及加锁原理说明:
一、表锁表锁由 MySQL Server 实现,锁定整张表,通常用于 DDL 操作(如 ALTER TABLE)或显式加锁场景。
读锁(共享锁,S 锁):多个事务可同时持有,允许读取但禁止修改。
写锁(排他锁,X 锁):仅允许持有事务修改,其他事务无法读取或修改。
使用一次性锁技术,加锁后只能操作已锁定的表。
会话持有其他表锁时执行 LOCK TABLE 或 START TRANSACTION 会释放原有锁。
行锁由存储引擎实现(如 InnoDB),锁定单行或多行数据,支持更高并发。行锁类型与索引使用及隔离级别密切相关。
1. 行锁的模式(兼容性)读意向锁(IS 锁):事务计划加行读锁时,先在表上加 IS 锁。
写意向锁(IX 锁):事务计划加行写锁时,先在表上加 IX 锁。
作用:快速判断表是否可加锁,避免遍历所有行锁。
兼容性矩阵:
示例:UPDATE user SET age=10 WHERE id=49 锁定主键 id=49。
无索引场景:全表扫描时,MySQL 会为所有行加记录锁,过滤后释放不满足条件的锁。
示例:在 RR 隔离级别下,UPDATE user SET age=10 WHERE id=49(记录不存在)会锁定 (30,49) 和 (49,50) 间隙。
特点:间隙锁之间互不冲突,仅阻止其他事务插入数据。
示例:索引 15,18,20,30,49,50 的 Next-Key 锁范围为 (-∞,15], (15,18], ..., (50,+∞)。
作用:解决非唯一索引下的幻读问题。
特点:
多个事务可在同一间隙加插入意向锁(互不冲突)。
与间隙锁或 Next-Key 锁冲突,阻止插入。
锁定范围示意图:

使用主键索引:直接在主键上加记录锁。
使用二级索引:先在二级索引上加记录锁,再根据主键回表加记录锁。
UPDATE user SET age=10 WHERE name='Tom'; -- 在 name='Tom' 和 id=49 上加锁逐行读取满足条件的记录,加记录锁后更新,直至无匹配记录。
在 RR 隔离级别下,可能加间隙锁或 Next-Key 锁防止幻读。
UPDATE user SET age=10 WHERE id>49; -- 可能加 Next-Key 锁 (49,50], (50,+∞)全表扫描并加记录锁,过滤后释放不满足条件的锁,性能极低。
死锁通常由多个事务竞争不同资源导致,例如:
规避建议:
MySQL 的锁机制通过表锁和行锁的组合实现数据一致性与并发性的平衡。理解锁类型、兼容性及加锁原理是优化性能和避免死锁的关键。实际开发中需结合隔离级别、索引使用及事务设计综合考量。