MySQL 如何解决不可重复读¶
一、问题¶
同一事务内,两次读同一行,结果不一样。
二、怎么解决¶
MVCC¶
每个版本有 roll_ptr,指向 undo log。
- 读的时候看版本链。
- 找自己能看到的版本。
ReadView¶
事务开始时生成 ReadView: - m_ids:活跃事务 ID。 - min_trx_id:最小活跃。 - max_trx_id:下一个要分配的。 - creator_trx_id:当前事务。
可见性判断¶
- 版本 trx_id < min_trx_id:可见。
- 版本 trx_id >= max_trx_id:不可见。
- 在 m_ids 里:不可见。
- 否则可见。
三、RC vs RR¶
- RC:每次 select 生成新 ReadView。
- RR:事务开始时生成一次 ReadView。
所以 RR 可重复读。
四、快照读 vs 当前读¶
- 快照读:普通 select,走 MVCC。
- 当前读:select for update,读最新。
一句话
MVCC + ReadView = 可重复读。