例如,如果我们有时间表 S1 :
r1[C] r2[A] r1[C] w3[B] w2[B] w1[C] commit1 r2[A] commit2 w3[B] commit3
我们知道这个调度不是冲突可序列化的,所以它不能来自两阶段锁定,但它是 View 可序列化的。但是,如果我们想将 Strict 2PL 应用于上述时间表,答案将是:x1[C] r1[C] s2[A] r2[A] r1[C] x3[B] w3[B] T2-waits-for-Xlock-on-B w1[C] commit1 u1[C] w3[B] commit3 u3[B] x2[B] w2[B] r2[A] commit2 u2[A] u2[B]
其中 u1[C] 表示 T1 释放对象 C 上的锁。在这种情况下,B 上的最后一次写入将由 T2 完成,这与原始调度 S1 不同。
或者 Strict 2PL 的正确应用如下:
x1[C] r1[C] s2[A] r2[A] r1[C] x3[B] w3[B] T2-waits-for-Xlock-on-B w1[C] commit1 u1[C] T3-waits-for-T2-to-take-lock-on-B-in-order-to-execute-w2[B]-first
在这种情况下,每个事务的读写顺序都会保留,但会发生死锁。
总结我的问题:在附表 S1 中应用 2 Phase Locking (Strict) 的正确方法是什么?
每次我们应用两阶段锁定时,是否必须保持命令的顺序与原始计划相同?
最佳答案
第一条经验法则是,如果调度中有两个不冲突的操作,它们可以互换。 S1 是 View 可序列化的,两者都是 w3[B]
的和 w2[B]
是盲写,它们也可以交换。为了应用严格的 2PL,我们需要保证 B 上的最后一次写入是由 T3 进行的,即结果调度中的最后一个操作应该是 w3[B]
.因此,我们可以交换第一个 w3[B]
与 w2[B]
答案应该是:
x1[C] r1[C] s2[A] r2[A] r1[C] x2[B] w2[B] T3-waits-for-Xlock-on-B w1[C] commit1
u1[C] r2[A] commit2 u2[A] u2[B] x3[B] w3[B] w3[B] commit3 u3[B]
关于locking - 2 相位锁定是否需要保持命令的顺序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65922532/