下面从分类体系 + 典型场景 + 面试高频点 三个层次,系统性讲清 MySQL 中的锁机制(以 InnoDB 为主)。
一、按「锁粒度」划分


1. 表级锁(Table Lock)
-
特点:锁整张表,开销小,并发能力差
-
常见类型
- 表共享锁(S)
- 表排他锁(X)
-
使用场景
- MyISAM 引擎(只支持表锁)
- InnoDB 在 DDL、
LOCK TABLES时使用
sql
LOCK TABLE user READ;
LOCK TABLE user WRITE;
2. 行级锁(Row Lock,InnoDB 核心)
- 特点:锁定记录(或记录区间),并发能力强,开销大
- 前提 :必须命中索引
- 使用场景:OLTP 高并发读写
sql
SELECT * FROM user WHERE id = 1 FOR UPDATE;
❗ 未命中索引 → 行锁退化为表锁
3. 页级锁(Page Lock)
- 特点:锁一页数据,介于表锁和行锁之间
- 说明:InnoDB 内部使用,对用户不显式暴露(了解即可)
二、按「锁模式」划分


1. 共享锁(S Lock)
- 读锁
- 多事务可同时加 S 锁
- 不允许写
sql
SELECT * FROM user WHERE id = 1 LOCK IN SHARE MODE;
2. 排他锁(X Lock)
- 写锁
- 加锁事务独占数据
- 阻塞其他读/写锁
sql
SELECT * FROM user WHERE id = 1 FOR UPDATE;
三、InnoDB 特有的三大行锁类型(面试重点)


1. 记录锁(Record Lock)
- 锁某一行记录
- 条件:唯一索引等值查询
sql
SELECT * FROM user WHERE id = 10 FOR UPDATE;
2. 间隙锁(Gap Lock)
- 锁的是 索引区间(不含记录)
- 防止幻读(插入新行)
- RR 隔离级别下启用
sql
SELECT * FROM user WHERE id BETWEEN 10 AND 20 FOR UPDATE;
3. 临键锁(Next-Key Lock)
- 记录锁 + 间隙锁
- InnoDB 默认锁策略(RR)
- 锁定范围:
(prev, current]
作用:彻底防止幻读
四、意向锁(Intent Lock)
表级锁,但为行锁服务
- IS(意向共享锁)
- IX(意向排他锁)
作用:快速判断表中是否存在行锁,避免逐行扫描
五、按「使用场景」再分类
1. 自动锁(隐式锁)
- DML 自动加锁
sql
UPDATE user SET name='A' WHERE id=1;
2. 显式锁
sql
SELECT ... FOR UPDATE;
LOCK TABLES user WRITE;
六、死锁(Deadlock)


产生条件
- 互斥
- 请求与保持
- 不可剥夺
- 循环等待
InnoDB 处理方式
- 自动检测死锁
- 回滚代价最小的事务
sql
SHOW ENGINE INNODB STATUS;
七、锁与事务隔离级别关系
| 隔离级别 | 是否使用间隙锁 | 是否可能幻读 |
|---|---|---|
| READ UNCOMMITTED | ❌ | ✅ |
| READ COMMITTED | ❌ | ✅ |
| REPEATABLE READ(默认) | ✅ | ❌ |
| SERIALIZABLE | 表级锁 | ❌ |
八、常见面试高频问题总结
1. 为什么"索引失效会导致锁表"?
行锁是基于索引实现的,未命中索引 → 无法定位行 → 锁整表
2. RR 下如何解决幻读?
Next-Key Lock(记录 + 间隙)
3. RC 与 RR 的锁差异?
- RC:无 Gap Lock
- RR:有 Gap / Next-Key Lock
4. MyISAM 与 InnoDB 锁区别?
| 引擎 | 锁类型 |
|---|---|
| MyISAM | 表锁 |
| InnoDB | 行锁 + 表锁 |
九、一句话总结(面试版)
MySQL InnoDB 通过行锁 + 间隙锁 + 临键锁,在 RR 隔离级别下有效解决幻读问题;锁是否生效,关键看索引是否命中。