SQL事务与锁是数据库面试中的核心内容,主要考察候选人对并发控制和数据一致性的理解程度。掌握事务的边界、隔离级别对异常现象的抑制能力,以及锁的粒度与冲突规则,能够帮你在面试中准确作答。

一、事务的ACID特性
面试通常先问事务是什么。事务是数据库操作的逻辑单元,具备四个特性:
- 原子性:事务内的操作要么全部成功,要么全部回滚。
- 一致性:事务前后数据满足业务约束,如账户总额不变。
- 隔离性:并发事务相互隔离,避免互相干扰。
- 持久性:提交后修改永久生效,即使宕机也不丢失。
二、事务隔离级别与并发异常
标准SQL定义四种隔离级别,不同级别解决不同的读异常:
| 隔离级别 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|
| 读未提交 | 可能 | 可能 | 可能 |
| 读已提交 | 避免 | 可能 | 可能 |
| 可重复读 | 避免 | 避免 | 可能(InnoDB下避免) |
| 串行化 | 避免 | 避免 | 避免 |
注意在MySQL的InnoDB引擎中,可重复读通过MVCC与间隙锁避免了幻读,这是面试常挖的细节。
查看与设置隔离级别
-- 查看当前会话隔离级别 SELECT @@transaction_isolation; -- 设置会话为读已提交 SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
三、锁机制常见考点
1. 共享锁与排他锁
共享锁(S锁)允许多个事务读同一行,排他锁(X锁)禁止其他事务加任何锁。二者互斥。面试常问:SELECT ... LOCK IN SHARE MODE加S锁,SELECT ... FOR UPDATE加X锁。
2. 行锁与表锁
当查询命中索引时InnoDB使用行锁;未命中索引会升级为表锁,这是线上事故高发点。可以用下面语句观察锁等待:
-- 查看当前锁信息(MySQL 8.0) SELECT * FROM performance_schema.data_locks;
3. 死锁与规避
两个事务互相等待对方持有的锁就会死锁。规避方式包括:按固定顺序访问多张表、缩短事务长度、降低隔离级别。数据库一般会自动检测并回滚代价小的事务。
四、乐观锁与悲观锁
悲观锁依赖数据库锁机制(如FOR UPDATE),适合写冲突多的场景。乐观锁通过版本字段在提交时校验,减少锁开销,适合读多写少。示例:
-- 乐观锁更新,version为版本列 UPDATE account SET balance = balance - 100, version = version + 1 WHERE id = 1 AND version = 3;
如果受影响行数为0,说明版本已被其他事务修改,需重试。
五、面试答题建议
回答事务与锁问题时,先讲概念再结合引擎实现(如InnoDB),并主动说明不同隔离级别下的现象差异。提到锁时区分粒度与模式,最后补充实战中避免死锁的做法,逻辑会更完整。