1
数据库原理与应用技术
1.7.2.3 6.2.3 活锁与死锁
6.2.3 活锁与死锁

封锁技术虽然较好地解决了并行操作的一致性问题,但同时,由于锁定了数据库对象,就有可能产生等待,等待的极端情况就是引起活锁和死锁。

1. 活锁

活锁(Live Lock)产生于循环依赖,是指某个事务永远处于等待状态而得不到执行的现象。此时,这个事务正在请求进行排他型封锁,而其他事务正在操作该数据。这种现象与死锁都是因为封锁方法不当造成的。

例如,事务T1封锁了数据对象R后,事务T2也请求封锁R失败而需要等待,于是T2等待。接着事务T3也请求封锁R失败而需要等待。事务T1释放R上的锁后,系统首先批准了T3的请求,T2仍然只能继续等待。接着事务T4也请求封锁R,T3释放R上的锁后,系统又批准了T4的请求,T2依然得继续等待……事务T2有可能就这样永远等待下去。这就是活锁的情形,如表6-4所示。

表6-4 活锁示例

2. 死锁

在事务和锁的使用过程中,死锁(Dead Lock)是一个不可避免的现象。

如果有两个事务分别锁定了两个单独的对象,而每个事务都在等待另外一个事务解除封锁,这样它才能执行下去,那么两个事务都处于等待状态,任何一个事务都无法执行,这种现象称为死锁。

如果事务T1锁定了数据对象R1,事务T2锁定了数据对象R2,然后事务T1又请求已被T2锁定的R2失败而需要等待,此时事务T2又请求已被T1锁定R1失败而需要等待。这就出现了T1在等待T2,而T2又在等待T1的局面,使T1和T2这两个事务永远没有结束的希望。这就是死锁的情况,如表6-5所示。

表6-5 死锁示例

解决死锁问题是由DBMS的一个死锁测试程序完成的。当发生死锁现象时,系统可以自动检测到。DBMS中的死锁测试程序定时检查是否发生死锁,若发现,则抽出某个事务作为牺牲品,把它撤销做回退操作,解除所有封锁,恢复事务到初始状态,释放的数据分配给其他事务,从而消除死锁现象。在发生死锁的两个事务中,根据事务处理时间的长短来确定它们的优先级。处理时间长的事务具有较高的优先级,处理时间较短的事务具有较低的优先级。当发生冲突时,保留优先级高的事务,取消优先级低的事务。