← ReJava · 学习目录

REJAVA / LEARNING NOTES

第12课速查:MVCC(多版本并发控制)与可见版本

随时回查术语、规则和示例;完整解释见对应课程。

Java 17 / 21更新于 2026.10.12约 3 分钟阅读

根据课程材料整理

本次更新说明
  • 整理为公开学习笔记,保留要点、对照表与练习入口。

返回完整课程

一行数据为什么能读出旧值

当前聚簇索引记录上的 DB_TRX_ID(最近修改事务编号)标识修改者,DB_ROLL_PTR(回滚指针)指向撤销记录。undo log(撤销日志)保存还原旧行所需的信息;顺着这些信息逐步还原,形成逻辑上的 version chain(版本链)。不是每个事务各复制一张表,也不保证所有历史永远保留。

按这四步找可见版本

范围:普通一致性读,已有记录的更新;从当前版本开始检查。Read View(读视图)保存建立时的活跃读写事务名单、上下边界和创建者信息。

  1. 自己的修改:可见。
  2. 其他修改者编号小于下边界:可见。
  3. 其他修改者编号大于或等于上边界:不可见。
  4. 处于两边界之间:在建立时名单里不可见,不在则可见。

不可见就沿撤销信息还原上一个版本;找到第一个可见版本即停止。编号是修改事务编号,不是业务主键或提交顺序。旧名单不因别人后来提交而刷新。

用一个例子连起来

A只读,在同一可重复读事务复用旧视图:下边界100、上边界110、名单100和105。100改别的记录;103已提交;105在视图建立时未提交,后来提交,再由112修改并提交。有效版本链从新到旧为112写13→105写11→103写9。

版本为什么动作
112写13112≥110不可见,往旧找
105写11在旧名单里不可见,往旧找
103写9100≤103<110,且不在名单里返回9,停止

若另一查询明确使用新视图:名单100,下边界100、上边界113,则112版本可见,返回13。这里的编号是假设,不是数据库实测输出。

何时换视图

  • READ COMMITTED(读已提交):每次普通一致性读使用新的快照。
  • REPEATABLE READ(可重复读):同一事务复用首次一致性读建立的快照。

普通开始事务不等于立即建立快照;自己的写入仍可见。以上不是锁定读和写操作的完整规则。

容易漏的边界

  • 写事务提交后,旧视图可能仍需 update undo(更新撤销信息)。满足清理条件后,由 purge(历史清理)后台处理。
  • 长时间保留旧视图可能拖住历史清理。查询完成后及时结束事务,避免开着事务等待用户操作。
  • 快照读不阻止别人审批;并发审批需要合适的锁或条件更新,并检查执行结果。
  • 活跃名单为空仍有上边界,未来的其他事务版本不会因此全部可见。

源码对照(mysql-8.4.0):m_up_limit_id是可见性下边界,m_low_limit_id是可见性上边界。名字容易记反,本课不要求背字段名。

复习与主来源

遮住例子,先自己说112、105、103各自怎样判断;隔日换编号再做。能跟着答案读懂,不等于能独立讲清楚,也不等于隔几天还记得。

主读官方多版本存储,配读一致性非锁定读;精确可见性判断见固定版本源码。有疑问时,先写清具体版本链和视图,再回到课程第三、四节逐步核对。

返回完整课程 · 检验 · 课后问答 · 课程目录