订阅更新

事务隔离级别和 MVCC 怎么理解?

面试问 164 约 2 分钟读完

本文目录
  1. 面试怎么回答
  2. 先从并发现象讲起
  3. 四个隔离级别解决的问题不同
  4. MVCC 为什么能降低读写阻塞
  5. 快照读不等于业务一定正确
  6. 一个典型场景
  7. 参考资料

面试怎么回答

隔离级别规定一个事务可以观察到哪些并发修改,MVCC 通过版本链和快照可见性实现高并发读取,两者不是同一个概念。Read Committed 常按语句取快照,Repeatable Read 更强调事务内一致快照,Serializable 还要防止无法串行化的组合结果。落地时我会结合原子更新、约束、锁或冲突重试,并关注长事务导致的版本膨胀。

先把这段讲顺;面试官追问时,再展开下面的原理和细节。

详细讲解

同一笔订单,在一个事务里读了两次,金额却变了。

这不是数据库随机返回,而是隔离级别允许的并发现象。

隔离级别定义允许看到什么,MVCC 是实现并发读写的一类机制,两者不能画等号。


先从并发现象讲起

脏读是读到了其他事务尚未提交的数据;不可重复读是同一行前后两次读取结果不同;幻读是同一条件查询出现或消失了记录。不同数据库对标准隔离级别的具体实现可能不同,面试时应先讲标准,再说明自己使用数据库的实际语义。

四个隔离级别解决的问题不同

Read Uncommitted 隔离最弱;Read Committed 通常让每条语句看到开始时已提交的数据;Repeatable Read 让事务内多次读取保持更稳定的快照;Serializable 要求并发执行效果等价于某种串行顺序。隔离越强,并不只是锁越多,也可能通过冲突检测并要求事务重试。

隔离级别关注的是可观察语义

MVCC 为什么能降低读写阻塞

MVCC 为记录保留多个版本,并用事务快照判断哪个版本可见。读操作可以读取符合可见性规则的历史版本,写操作创建新版本,因此常见读写不必互相等待。但多个版本需要回收,长事务会阻碍旧版本清理并放大存储和扫描成本。

快照读不等于业务一定正确

两个事务都读到库存为 1,再分别执行扣减,如果只依赖读快照,仍可能出现丢失更新或写偏差。常见处理包括原子条件更新、唯一约束、显式锁、乐观版本号,以及在 Serializable 冲突后重试。

MVCC 的核心链路

一个典型场景

值班系统要求每个班次至少一名医生。两个事务分别看到还有两人值班,各自把自己改为休息;单行约束都合法,组合结果却违反业务规则。这类写偏差说明一致性不能只看单行快照,还要用串行化、锁定共同条件或把规则落成可约束的数据模型。

参考资料

刷题进度保存在当前浏览器