跳转至

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 = 可重复读。