zoukankan      html  css  js  c++  java
  • 数据库死锁解决方案

    一、活锁
    如果事务T1封锁了数据R,事务T2又请求封锁R,于是T2等待。T3也请求封锁R,当T1释放了R上的封锁之后系统首先批准了T3的请求,T2仍然等待。然后T4又请求封锁R,当T3释放了R上的封锁之后系统又批准了T4的请求,...,T2有可能永远等待,这就是活锁的情形。 
    避免活锁的简单方法是采用先来先服务的策略。
    二、死锁
    如果事务T1封锁了数据R1,T2封锁了数据R2,然后T1又请求封锁R2,因T2已封锁了R2,于是T1等待T2释放R2上的锁。接着T2又申请封锁R1,因T1已封锁了R1,T2也只能等待T1释放R1上的锁。这样就出现了T1在等待T2,而T2又在等待T1的局面,T1和T2两个事务永远不能结束,形成死锁。
    1. 死锁的预防
    在数据库中,产生死锁的原因是两个或多个事务都已封锁了一些数据对象,然后又都请求对已为其他事务封锁的数据对象加锁,从而出现死等待。防止死锁的发生其实就是要破坏产生死锁的条件。预防死锁通常有两种方法:
    ① 一次封锁法 
    一次封锁法要求每个事务必须一次将所有要使用的数据全部加锁,否则就不能继续执行。
    一次封锁法虽然可以有效地防止死锁的发生,但也存在问题,一次就将以后要用到的全部数据加锁,势必扩大了封锁的范围,从而降低了系统的并发度。
    ② 顺序封锁法 
    顺序封锁法是预先对数据对象规定一个封锁顺序,所有事务都按这个顺序实行封锁。
    顺序封锁法可以有效地防止死锁,但也同样存在问题。事务的封锁请求可以随着事务的执行而动态地决定,很难事先确定每一个事务要封锁哪些对象,因此也就很难按规定的顺序去施加封锁。
    可见,在操作系统中广为采用的预防死锁的策略并不很适合数据库的特点,因此DBMS在解决死锁的问题上普遍采用的是诊断并解除死锁的方法。
    2. 死锁的诊断与解除
    ① 超时法
    如果一个事务的等待时间超过了规定的时限,就认为发生了死锁。超时法实现简单,但其不足也很明显。一是有可能误判死锁,事务因为其他原因使等待时间超过时限,系统会误认为发生了死锁。二是时限若设置得太长,死锁发生后不能及时发现。
    ② 等待图法
    事务等待图是一个有向图G=(T,U)。 T为结点的集合,每个结点表示正运行的事务;U为边的集合,每条边表示事务等待的情况。若T1等待T2,则T1、T2之间划一条有向边,从T1指向T2。事务等待图动态地反映了所有事务的等待情况。并发控制子系统周期性地(比如每隔1分钟)检测事务等待图,如果发现图中存在回路,则表示系统中出现了死锁。

    DBMS的并发控制子系统一旦检测到系统中存在死锁,就要设法解除。通常采用的方法是选择一个处理死锁代价最小的事务,将其撤消,释放此事务持有的所有的锁,使其它事务得以继续运行下去。当然,对撤消的事务所执行的数据修改操作必须加以恢复。

    银行算法
    避免死锁算法中最有代表性的算法是Dijkstra E.W 于1968年提出的银行家算法:
    该算法需要检查申请者对资源的最大需求量,如果系统现存的各类资源可以满足申请者的请求,就满足申请者的请求。
    这样申请者就可很快完成其计算,然后释放它占用的资源,从而保证了系统中的所有进程都能完成,所以可避免死锁的发生。








  • 相关阅读:
    Count and Say leetcode
    Find Minimum in Rotated Sorted Array II leetcode
    Find Minimum in Rotated Sorted Array leetcode
    Search in Rotated Sorted Array II leetcode
    search in rotated sorted array leetcode
    Substring with Concatenation of All Words
    Subsets 子集系列问题 leetcode
    Sudoku Solver Backtracking
    Valid Sudoku leetcode
    《如何求解问题》-现代启发式方法
  • 原文地址:https://www.cnblogs.com/iamconan/p/7383529.html
Copyright © 2011-2022 走看看