跳到正文

第8章学习笔记:事务、隔离与并发控制

课程笔记

用调度、可串行化、锁和 MVCC 推导并发正确性,而不是背隔离级别名称。

关联:章节 第8章 事务、隔离与并发控制

第8章笔记:事务、隔离与并发控制

本章不是七个并列名词

用调度、可串行化、锁和 MVCC 推导并发正确性,而不是背隔离级别名称。 学习顺序从《ACID 是一组可检验承诺》开始,到《隔离级别的实验化选择》闭合。每一节都要留下下一节能直接使用的对象:模式、关系、查询结果、页、计划、事务状态、日志记录或部署证据。若你只能逐条背定义,却说不清前一节输出怎样成为后一节输入,这一章还没有真正连起来。

七节依赖与例题

1. ACID 是一组可检验承诺

要解决的问题: 原子性保证全做或全不做,一致性依赖约束与事务逻辑,隔离性限制并发可见效果,持久性保证提交后抗故障。

跟着做: 银行转账要同时扣款与入账;余额非负是业务一致性;两个转账并发不能丢更新;提交确认后崩溃仍能恢复。

验收规则: ACID 各自有不同故障模型和验收方法,不能用‘用了事务’一语带过。

2. 调度与冲突可串行化

要解决的问题: 调度保留各事务内部顺序;若冲突操作形成的优先图无环,则调度冲突可串行化。

跟着做: T1 写 A 在 T2 读 A 前形成 T1→T2,若另一对象又形成 T2→T1 就出现环,无法等价为串行顺序。

验收规则: 优先图节点是事务,边来自同一数据项上至少一个为写的有序操作;无环即可拓扑排序。

3. 脏读、不可重复读与幻读

要解决的问题: 异常应从具体操作序列理解:读未提交值、同一行两次读不同、同一谓词集合变化分别对应不同可见性问题。

跟着做: 库存审计两次查询 quantity<0,中间另一个事务插入异常行,第二次多出一行,这是谓词范围的幻读。

验收规则: 隔离级别名称因实现可能有差异,验收应写并发脚本观察允许的历史。

4. 两阶段锁与锁粒度

要解决的问题: 严格两阶段锁在提交前持有写锁,保证可串行化和可恢复;行、页、表锁在并发度与管理开销间权衡。

跟着做: 批量更新大量行可能触发锁升级并阻塞在线请求;意向锁让系统快速判断层级冲突。

验收规则: 增长阶段只加锁,收缩阶段只释放;严格 2PL 把排他锁至少持有到提交或回滚。

5. 死锁检测、预防与重试

要解决的问题: 死锁由互斥、占有等待、不可剥夺和循环等待共同构成;系统可检测等待图环并选择牺牲者。

跟着做: 两个事务以相反顺序锁 account 1 和 2 会互等;统一按账户 id 加锁可破坏循环等待。

验收规则: 等待图有环表明死锁;应用重试需回滚完整事务、加入退避并保证幂等。

6. MVCC 与快照

要解决的问题: MVCC 保存行版本,让读者按快照时间选择可见版本;它减少读写阻塞,但不自动消除写偏斜。

跟着做: 两名医生各看到另一人值班,于是同时取消自己,单行冲突不存在却违反‘至少一人值班’约束。

验收规则: 可见性由版本创建/删除事务与快照决定;跨行不变量需要串行化、显式锁或约束重构。

7. 隔离级别的实验化选择

要解决的问题: 选择隔离级别应先列业务不变量和允许历史,再用并发测试证明;更强隔离会带来冲突重试或阻塞成本。

跟着做: 抢最后一张票必须原子条件更新或串行化,浏览商品列表可接受较弱快照;二者不该机械共用一种策略。

验收规则: 正确策略 = 最小足够隔离 + 原子条件写 + 冲突处理 + 并发回归测试。

章内共同推理方法

先写“一行或一个状态代表什么”,再写它必须满足的键、约束、顺序或故障假设。遇到 SQL,先定结果粒度和重复/NULL 语义,再编码;遇到存储与优化,先估算页数、基数和 I/O,再看真实执行计划;遇到事务与分布式,先画时间线和允许历史,再讨论隔离级别、日志或共识。任何公式都要带单位、数据分布和适用边界。

可复现练习

从本章七个例题中任选两个,用 SQLite 或课程给定模型从空环境重做。保存建表/输入、执行步骤、实际输出和断言;随后故意加入一个重复键、NULL、并发交错、崩溃点、倾斜分布或网络分区,记录第一个被破坏的不变量。只截成功界面、只贴 SQL 或只报告耗时不算完成。

闭卷验收

用十分钟画出本章七节箭头图;任选一条箭头解释传递的具体字段、状态或证据。再为《隔离级别的实验化选择》写一个最小失败案例,并追溯它需要《ACID 是一组可检验承诺》中的哪条定义才能修复。最后列出三道题:一道唯一答案判断、一道多条件选择、一道必须计算或写 SQL/状态轨迹的问题,且每题都写清为什么其他答案错。