对2PL的一些补充
主要的资料来自于wiki
2PL有两个经典的变体,分别是S2PL(strict-2PL)和SS2PL(strong strict-2PL or rigorous-2PL)
我们通过这张图来理解2PL以及其他相关的一些并发控制手段
S2PL即所有的写锁在事务提交的时候才能释放
SS2PL则是对于所有的锁,都只能在事务提交的时候才能释放
S2PL可以保证不会脏读,因为任何处于活跃事务中的数据项都会处于写锁中。所以只要我们通过读锁来保证我们读到的数据项没有被写锁占有,那么这个数据项就是一致的,即不会脏读
而对于SS2PL来说,虽然一定程度上降低了并发度,但是他有两个额外的好处
首先就是没有了对2PL两阶段处理的额外开销,也就是说我们现在不需要再去跟踪这个事务来到了第几个阶段,是不是可以进入shrinking阶段了
其次就是他提供了一个额外的属性,CO(commitment ordering)
表示的是我们事务的执行顺序是按照提交的顺序来的
考虑这样一个例子,两个事务T1,T2。T1首先处理完所有的数据,并且释放了所有的锁,但是还没有提交
这时候T2出现,修改了部分T1中读到的值,然后T2提交,接着T1提交
虽然这个调度是可串行的,但是比较反直觉的是,T2先于T1提交,但是T1中并没有读到T2中修改的那些数据项。
我们这个调度实际上是等同于T1先于T2执行,但是结果是T2先于T1提交
当我们应用SS2PL的时候,就可以保证,提交的顺序就是串行化执行的顺序
这一点在分布式数据库中是一个比较关键的属性,具体的,wiki上提到CO是全局串行化(global serializability)的一个重要保证
所以SS2PL是更加受人欢迎的一种实现方法
单独的CO比较类似我们见到的OCC,基于有效性检查的协议,但是他的写不是应用于局部变量,所以也就导致了可能的级联回滚
回到上面的图片,我们可以看到2PL可以保证串行化,但是不能保证可恢复
而单独的CO虽然也保证了可串行化,但是也不能保证可恢复
要注意到CO是分在non-blocking中的
看图可以发现,如果要保证不会级联撤销,我们就需要blocking的手段
这里的strictness我还没有找到具体的解释,但是看图可以发现,应该就是指写锁不能在提交时释放的意思
而满足了strictness的S2PL自然也就满足了无级联撤销的特性,所以是可恢复的
最下面的SS2PL则又满足了CO,是满足特性最多的一种协议
文章评论