“本页采用数据库教材中常称 rigorous 2PL 的严格口径:事务的共享锁和排他锁都持有到 commit 或 abort,再统一释放。有些文献把“strict 2PL”限定为只把排他锁持有…”
形式陈述 ​
事务调度
且二者之间没有
严格性立即排除脏读,所以严格事务调度是 无级联事务调度 的更强子类,进而可恢复。严格两阶段锁把冲突锁持有到事务结束,是生成严格调度的一种充分机制;它不是必要条件,也不与严格性定义等价。
“严格调度”不要与严格可串行化混淆。前者约束未提交写的可访问性,后者要求事务等价于尊重实时先后的串行顺序。严格调度本身甚至不必冲突可串行化。
对每个数据项,严格性把一次写到写者终止之间形成保护区间。其他事务可在区间之前访问旧值,也可在区间之后访问提交值或恢复值;唯独不能穿过区间内部。这个逐项条件允许无关写集继续并发。
直觉
一次未决定的写像施工中的路段。严格调度不只禁止行人读取路面状态,也禁止另一施工队在上面继续覆盖;原事务提交或中止后,路段才重新开放。于是恢复管理器撤销一个 loser 时,不必担心别的事务已经在它的脏值上读写。
限制只跟随写集。两个只读事务可以同时访问,同一事务写 A 时,其他事务仍可处理无关的 B。性能取决于写热点与锁粒度,而不是简单地“严格就全部串行”。
严格性为恢复提供干净切口:写者若 abort,保护区间内没有外来读写需要解释;写者若 commit,后续访问从已决定版本继续。它不要求数据库页面从未包含脏字节,只要求逻辑访问权在决定前不交给其他事务。
例子与边界
若执行
w1(x,10); r2(y)->7; w2(y,8); c2; c1; r3(x)->10
严格也不蕴含冲突可串行化。考虑
r1(x); r2(y); w1(y); c1; w2(x); c2
每次写后都没有其他事务在写者结束前访问同一项,所以调度严格;但
在页级锁实现中,对同页不同记录的更新也可能互相等待;这是保守的物理粒度,不改变逻辑定义。反过来,只锁记录而遗漏索引项或溢出页,可能让物理写绕过声明的严格保护。
多版本实现可以保留旧版本供读取,同时把新未提交版本隐藏;这种读取不访问
推论与应用
严格调度使 UNDO 更局部:崩溃恢复可以撤销未提交写,而不需要撤销已经读取或覆盖这些写的后继事务。它还禁止两笔未提交写互相覆盖,避免恢复时无法确定应恢复哪一个 before-image。
严格性、可串行化与持久性应分别测试。锁 trace 可证明未提交写未泄露,冲突图可证明串行次序,WAL 与重启 trace 则证明崩溃后的状态;任一证据都不能替代另外两项。
该层级的包含方向可用反例逐级验证:可恢复但有脏读的调度不是无级联;无级联但有脏写的调度不是严格。测试若只生成读依赖,会永远看不见第二个严格包含,因此还必须包含并发写写场景。
参考资料
- Philip A. Bernstein, Vassos Hadzilacos, and Nathan Goodman, Concurrency Control and Recovery in Database Systems, Addison-Wesley, 1987, Chs. 3 and 6。
- Jim Gray and Andreas Reuter, Transaction Processing: Concepts and Techniques, Morgan Kaufmann, 1992, Chs. 7 and 10。
- Abraham Silberschatz, Henry F. Korth, and S. Sudarshan, Database System Concepts, 7th ed., McGraw-Hill, 2019, Chs. 18–19。