2008年(239)
分类: DB2/Informix
2008-06-17 23:20:21
假定存在两个事务A和B。事务A申请由事务B拥有的锁,进入等待状态;同时事务B申请由事务A拥有的锁,同样进入等待状态。结果A、B两个事务互相等待,都不能够继续处理。我们把这种情况称为死锁。当然,这里展示的事例是一个比较特殊的情况,只有两个事务参与了死锁。一般情况下的死锁,是在多个事务组之间形成了等待环而引起的。
一个被很好设计、编写的应用系统,不应当有死锁的发生。而一旦出现死锁,数据库系统本身应当有能力解除死锁。处理死锁问题的方法很多,主要有以下两种思路:
(1)使用死锁预防措施,使系统永不进入死锁状态。
(2)允许系统进入死锁状态,使用死锁检测与恢复机制进行恢复。
1. 死锁预防
使数据库系统不会出现死锁问题,是死锁预防策略的关键所在。可以使用以下两种方式实现:
(1)事务同时获得所有锁
每个事务在开始之前,一次性锁定它要处理的所有数据。只要有一个锁没有被授予,事务就不能执行,并且立即释放所有已经获得的锁。事务只有在同时获得所有的锁之后,才能开始处理。
这种处理死锁的方式,虽然简单、明了,但缺点也很明显。首先,在事务开始前通常很难预知那些数据需要锁定。其次,数据使用率很低,因为许多数据虽然被封锁,但长时间不会被使用。
(2)对加锁请求进行排序
在应用系统设计和开发时,对所有的数据定义一个序列,要求所有事务只能按照该序列规定的顺序锁定数据。由于对数据的访问按照相同的顺序进行,不会出现事务之间的互相等待,从而避免了死锁的发生。
这种策略操作简单,实现起来很方便,应用系统设计及开发人员应当考虑这种避免死锁的方法。另外,对先查询、然后更新数据的事务,可以在查询时直接使用更新锁,也会降低死锁发生的可能性。
2. 死锁检测与恢复
死锁检测与恢复机制用来发现、然后处理系统中发生的死锁。系统周期性地检测,判断有无死锁发生。如果发生死锁,则系统必须从死锁中恢复。
数据库系统的运行需要维护事务的锁信息,包括:已经拥有、正申请以及正等待的锁信息。死锁检测程序利用这些信息,运用相关算法,判定系统是否出现了死锁。当检测算法判定存在死锁时,系统必须从死锁中恢复。解除死锁最通常的做法是回滚一至多个事务。
3. 锁等待超时机制
我们前面讲到的锁等待超时机制,也可以用来处理死锁。申请锁的事务至多等待一个给定的时间。如果在此期间锁没有被授予该事务,那么此事务超时,然后回滚。如果系统中确实存在死锁,那么卷入死锁的一个或者多个事务将由于超时而回滚,从而使其他事务继续执行。
该机制介于死锁预防与死锁检测及恢复之间。但是,一般很难确定一个事务超时之前应该等待多长时间。如果已经发生死锁,则等待时间太长而导致不必要的延迟。如果等待时间太短,即使没有死锁,也可能引起事务回滚,造成系统资源的浪费。