事务处理-2PL下的死锁与饥饿
2PL——2阶段锁存在的问题
两阶段锁协议通常包括扩张和收缩两个阶段。在扩张阶段,事务将获取锁,但不能释放任何锁。在收缩阶段,可以释放现有的锁,但不能获取新的锁。上图是一个典型的遵循2PL协议的序列表。看似严格保证了序列化,但实际存在着死锁的风险。
例如:当T1’在扩张阶段,获取了Y的读锁,并读取了Y,此时想要去获取X的写锁,却发现T2’的读锁锁定了X,而T2’也想要获取Y的写锁。简而言之,T1’不得到X是不会释放Y的,T2’不得到Y也是不会释放X的,这便陷入了循环,便形成了死锁。
本文就这一问题展开对死锁的两种处理方法的介绍,希望能用更通俗的语言让大家理解
一、死锁与等待图
1. 死锁(Deadlock)
死锁是指集合中的每个事务都在等待队列中,等待其他事务释放某个项上的锁。但是因为另一个事务也在等待,所以它永远不会释放锁。简而言之就是,我在等你主动,你也在等我主动,最后的结果是我俩都陷入僵局,什么都做不了。
通常检验一个事务执行序列是否发生死锁,可以用等待图(wait-for graph)来形象地描述。还是拿上面的例子来说。
图(a)就是我在上文中描述死锁的产生过程。图(b)就是等待图,从图中我们可以形象地看到,T1’在向T2’索取X,T2’在向T1索取Y,这便在图中形成了环,便发生了死锁。
死锁一旦发生,进程或事务将面临饥饿(Starvation),甚至最终饿死。