|
5. 死锁
��两个并发执行的事务可能发生死锁。当每个事务都企图对另一事务已加锁的数据单元再行加锁时,就可能发生死锁。
一个事务如果申请锁而未获准,则需等待其他事务释放锁,这就形成了事务间的等待关系。当事务之间出现循环等待时,如果不加干预则会一直等待下去,即出现死锁。因此,死锁发生时,至少有两个或多个事务同时处于相互等待状态,即每个事务都在等待其他事务释放锁才能继续执行。图7-14是两个事务相互等待出现死锁的情况。
图7-14 两个事务出现死锁
��在多个并发的事务之间出现死锁现象是可能的,下面的条件是发生死锁的充分必要条件:
��① 互斥条件:事务请求对资源的独占控制。
��② 等待条件:事务已持有一定资源,又去申请并等待其它资源。
��③ 非抢占条件:直到资源被持有它的事务释放之前,不可能将该资源强制从持有它的事务夺去。
��④ 循环等待条件:存在事务相互等待的等待圈。
��图7-15是三个事务相互等待的示例。
图7-15
��发生死锁以后,DBMS必须采取措施解决死锁。解决死锁一般采用两种方法:预防死锁,以及检测与解除死锁。
��(1) 预防死锁预防死锁的方法较多,主要可以采用如下两种预防死锁的方法:
��● 一次封锁法:一次封锁法要求每个事务必须一次将所有要使用的数据全部加锁,否则就不能继续执行。
��● 顺序封锁法:顺序封锁法是预先对数据对象规定一个封锁顺序,所有事务都按这个顺序实现封锁。
��(2) 死锁的检测与解除如果允许数据库中出现死锁,应尽可能及时发现和处理,死锁的检测一般使用超时法或等待图法。
��● 超时法:如果一个事务的等待时间超过了规定的时限,则认为发生了死锁。
��● 等待图法:事务等待图是一个有向图G=(T, U),T为结点的集合,每个结点表示正在运行的事务;U为边的集合,每条边表示事务等待的情况。若事务T1等待事务T2,则T1,T2之间有一条有向边,从
T1 指向 T2。如果发现图中存在回路,则表示系统中出现了死锁。
��发现死锁后,靠事务本身无法打破死锁,必须由DBMS干预。DBMS对死锁一般作下列处理:
��● 在循环等待的事务中,选一个事务,将该事务撤销,释放其获得的锁及其它资源;
��● 将释放的资源分配给等待该事务的其它事务。
��综上所述有两种类型的访问同步: 一种是乐观派,假定访问冲突很难发生,事务可在不需要任何加锁的情况下访问所需要的对象,这只适合单用户单进程的操作。另一种就是由DBMS记录所有的访问,一旦在事务执行期间发生访问冲突,就UNDO
该事务。这后一种方法在具体实现中有许多具体的实现策略。
|
|