Conflic Serializable和两阶段锁

Conflic Serializability

定义Conflicting Operations:


image.png

定义Conlict Serializable:


image.png

如果某种调度S使得事务的前驱图是无环的,那么说明这个调度S是conflict serializable,如果有环,则说明这个调度S不满足conflict serializable。

Strict Two Phase Locking 就是在2PL的基础之上,增加以下限制:
all locks are released together when transaction completes, either:

  1. Transaction has committed. OR
  2. Transaction has aborted.

以解决Cascading Aborts的问题。

需要思考,为什么满足无环,就是可串行的?因为可以通过移动操作,使得两个T1和T2和串行的结果一样。见https://www.youtube.com/watch?v=h8Xzy6DANzw

两阶段锁

两阶段锁是数据库事务中的一种concurrency control method,它可以保证多个事务的可串行化(serializability)。说白了就是保证事务的ACID。两阶段锁协议可以保证调度是满足Conlict Serializable的。

两段锁协议是指每个事务的执行可以分为两个阶段:生长阶段(加锁阶段)和衰退阶段(解锁阶段)。
加锁阶段:在该阶段可以进行加锁操作。在对任何数据进行读操作之前要申请并获得S锁,在进行写操作之前要申请并获得X锁。加锁不成功,则事务进入等待状态,直到加锁成功才继续执行。
解锁阶段:当事务释放了一个封锁以后,事务进入解锁阶段,在该阶段只能进行解锁操作不能再进行加锁操作。

另外要注意两段锁协议和防止死锁的一次封锁法的异同之处。一次封锁法要求每个事务必须一次将所有要使用的数据全部加锁,否则就不能继续执行,因此一次封锁法遵守两段锁协议;但是两段锁协议并不要求事务必须一次将所有要使用的数据全部加锁,因此遵守两段锁协议的事务可能发生死锁。

可以证明,若并发执行的所有事务均遵守两段锁协议,则对这些事务的任何并发调度策略都是可串行化的。
我们可以证明,在使用两段锁协议的情况下,T1、T2、Tn的前驱图里,是不会有环路出现的。证明的方法可以用反证法。不妨假设T1 T2 T3的前驱图,形成了一个环:T1 -> T2 -> T3 -> T1,并且T1、T2、T3都遵守两段锁,那么就有下图:

image.png

A、B、C是需要加锁的资源。
t1 t2 t3...t7是各个事务中加锁、解锁的时间。
由两阶段锁的协议可知,T1必须释放了A的锁,T2才可能加上A的锁,所以t2 t1 < t2 < t3 < t4 < t5 < t6 < t7。
t2是release(A)操作,t7是lock(c)操作,我们知道两阶段锁协议中,开始release锁后,就不再允许加锁了,得出矛盾。

参考资料

  1. 数据库中的two phase locking
  2. 如何画前驱图
  3. https://www.youtube.com/watch?v=V27Myhkj4Mg
  4. https://www.youtube.com/watch?v=h8Xzy6DANzw

你可能感兴趣的:(Conflic Serializable和两阶段锁)