在数据库中,死锁是一种不需要的情况,其中两个或多个事务无限期地等待对方放弃锁。死锁据说是DBMS中最令人担忧的复杂问题之一,因为它会导致整个系统停止。
例如—— 让我们用一个例子来理解死锁的概念: 假设事务T1在Students表中的某些行上持有锁,并且 需要更新 成绩表中的一些行。同时,交易 T2有效 锁定Grades表中的那些行(T1需要更新) 但是需要 更新学生表中的行的步骤 由交易T1持有 .
现在,主要问题出现了。事务T1将等待事务T2放弃锁,同样,事务T2将等待事务T1放弃锁。因此,除非DBMS检测到死锁并中止其中一个事务,否则所有活动都会停止并永远保持静止。
![图片[1]-数据库管理系统中的死锁-yiteyi-C++库](https://media.geeksforgeeks.org/wp-content/cdn-uploads/deadlock.png)
数据库管理系统中的死锁
避免死锁- 当数据库陷入死锁时,重启或终止数据库比终止死锁更好。死锁避免方法适用于较小的数据库,而死锁预防方法适用于较大的数据库。 避免死锁的一种方法是使用应用程序一致性逻辑。在上面给出的示例中,访问学生和成绩的事务应该总是以相同的顺序访问表。这样,在上面描述的场景中,事务T1只是等待事务T2在开始之前释放对等级的锁定。当事务T2释放锁时,事务T1可以自由进行。 另一种避免死锁的方法是同时应用行级锁定机制和读提交隔离级别。然而,它不能保证完全消除死锁。
死锁检测- 当事务无限期等待获取锁时,数据库管理系统应该检测该事务是否涉及死锁。
等待图表 是检测死锁情况的方法之一。这种方法适用于较小的数据库。在这种方法中,根据事务及其对资源的锁定绘制一个图。如果创建的图具有闭环或循环,则存在死锁。 对于上述场景,下面绘制了等待图
僵局预防—— 对于大型数据库,死锁预防方法是合适的。如果资源的分配方式使死锁永远不会发生,则可以防止死锁。DBMS分析这些操作是否会造成死锁,如果会,则永远不允许执行该事务。
死锁预防机制提出了两种方案:
- 等待死亡方案- 在这个方案中,如果一个事务请求一个被另一个事务锁定的资源,那么DBMS只需检查两个事务的时间戳,并允许较旧的事务等待资源可供执行。 假设有两个事务T1和T2,并且让任何事务的时间戳T为TS(T)。现在,如果其他事务锁定了T2,并且T1请求T2持有的资源,那么DBMS将执行以下操作:
检查TS(T1)
- 伤口等待计划- 在该方案中,如果较旧的事务请求较年轻的事务持有的资源,则较旧的事务将强制较年轻的事务终止该事务并释放该资源。较年轻的事务以一分钟的延迟重新启动,但时间戳相同。如果较年轻的事务正在请求由较年长的事务持有的资源,则要求较年轻的事务等待较年长的事务释放该资源。
下表列出了等待-死亡和创伤-等待计划预防计划之间的差异:
等等——死 | 伤口-等等 |
---|---|
它基于非抢占技术。 | 它基于抢占技术。 |
在这种情况下,较旧的事务必须等待较年轻的事务释放其数据项。 | 在这种情况下,较旧的事务从不等待较新的事务。 |
在这些技术中,中止和回滚的次数更高。 | 在这种情况下,中止和回滚的次数较少。 |
参考资料- 医生。神谕 等待死亡和受伤等待的区别 书—— Navathe的《数据库系统基础》