尽管数据库在死锁问题上普遍采用检测和解除的方法处理死锁,而不是预防。对DBMS预防死锁、活锁的方法还是有必要学习的。
三种主要策略:
- 一次性封锁(类似于静态资源分配,操作系统知识)
每个事务必须一次将所有要用的数据加锁,否则不能继续执行。
- 顺序封锁(请求序列,破坏循环等待条件,操作系统知识)
预先为数据对象规定一个封锁顺序,所有事务按照顺序进行封锁。
以上两种方法都不适用
,第一种效率很低,第二种执行困难。
第三种方法,也是比较难理解的一种方法:
- 时间戳(这个按照书面语挺难理解的,下面是我转述的,希望更好理解)
每个事务都给它一个时间戳,当A申请资源锁的时 候,B已经获得了锁,有以下两个策略
- wait-die(等待死亡):是一种非剥夺策略,老的事务等待新的事务释放资源,即若A比B老,则等待B执行结束,否则A卷回(roll-back),一段时间后会以原先的时间戳继续申请。老的才有资格等,年轻的全部卷回。
- wound-wait(伤害-等待):是一种剥夺策略,如果A比B年轻,A才等待,A比B老,则杀死B,B回滚。换句话说,老事务不等待"你",直接杀死"你",抢占资源,小孩子才等。
等待死亡的特点是不剥夺,但只有老的有资格等待。
伤害等待的特点是老的不等待,直接把你干掉,新的才去等待。
从某种意义上来说,这两者很类似,都是老事务优先(否则就会有饿死现象)
总结
两个方法都保证事务执行是单向的(要么老的等新的(等现存的持有锁的新事务结束,而不是说等所有新的事务申请结束了才执行老的),要么新的等老的),不会出现循环等待,从而避免了死锁,也都确保了老事务的优先权,不会活锁,所以时间戳法
是可采纳的。