“由于事务内部读发生在自身提交前,条件立即给出 $c i<r j(x)<c j$。所以每个无级联调度都是 可恢复事务调度,但反向不成立:可恢复性允许先脏读,只把消费者的 commit 延后。”
形式陈述 ​
设
换言之,消费者可以在生产者尚未提交时读取,但它自己的 commit 必须等待生产者的 commit。若生产者中止,所有依赖该值且尚未提交的消费者也必须中止;可恢复性确保系统尚有机会这样做。
该性质只约束提交次序,不禁止脏读,也不要求调度可串行化。reads-from 必须指向具体写入版本;仅从两个事务都访问过
若 reads-from 形成链
直觉
把未提交值看成一张尚未兑现的支票。下游事务可以先拿它计算,却不能在支票兑现前把自己的结果标成不可撤销。否则上游一旦中止,下游已经对外承诺的结果便失去来源。
可恢复调度因此是一条“承诺不得超车”的规则,而不是“不许提前看”。更强的无级联调度会把读取本身推迟到写者提交之后;严格调度还会阻止覆盖未提交写。
这条规则保护的是 commit 的不可逆边界。消费者在内存中做了大量计算仍可撤销,只要尚未承诺;一旦它向客户端确认、释放依赖资源或触发不可回滚副作用,再要求它跟随上游 abort 就已经太晚。
例子与边界
调度
w1(x,20); r2(x)->20; c1; c2
是可恢复的。
把末尾改成
w1(x,20); r2(x)->20; c2; a1
便不可恢复。
若
三级链更能看到级联成本:
w1(x); r2(x); w2(y); r3(y); a1
若允许这些脏读,
推论与应用
无级联事务调度把
可恢复性与持久日志仍是两件事。提交次序正确,却没有把
提交协调器可以按依赖图延迟消费者,将多个已经满足前置的事务批量刷入日志。优化不能颠倒边:group commit 可让
参考资料
- Philip A. Bernstein, Vassos Hadzilacos, and Nathan Goodman, Concurrency Control and Recovery in Database Systems, Addison-Wesley, 1987, Chs. 2 and 6。
- Jim Gray and Andreas Reuter, Transaction Processing: Concepts and Techniques, Morgan Kaufmann, 1992, Chs. 6 and 10。
- Abraham Silberschatz, Henry F. Korth, and S. Sudarshan, Database System Concepts, 7th ed., McGraw-Hill, 2019, transaction recovery chapter。