标准答案
- 脏读会让事务依据后来被回滚的数据做决定,因此通常不被核心业务接受。
- 不可重复读关注同一已存在记录被其他事务提交修改后,本事务再次读取看到新值。
- 幻读关注满足范围条件的记录集合变化,例如两次查询待处理订单数量不同。
- MVCC 快照读、当前读、锁定读和隔离级别会影响这些现象是否出现,不能只用教科书名称判断。
- 很多所谓幻读实际是应用在两次查询间改变了筛选条件、租户上下文或分页排序,应先排除逻辑问题。
题目解析
异常名称的价值在于帮助明确需要保护的观察结果。业务并不总是要求“事务内所有列表永远不变”,它可能只需要扣减时不超过库存、审批时不覆盖他人修改。应先定义不变量,再选择控制方式。
在 MVCC 数据库中,普通一致性读常使用快照,而 UPDATE 或 SELECT FOR UPDATE 是当前读,二者观察到的版本不同。排查并发 bug 时必须区分代码究竟做了哪一种读。
常见误区
- 把任何两次查询结果不同都称为幻读,没有区分单行值变化和范围集合变化。
- 忽略读写是否在同一事务、是否自动提交,导致复现条件与线上完全不同。