什么是数据库中的死锁?

Ven*_*avu 16 database deadlock sql-server-2005 database-deadlocks

sql server中的死锁是什么时候出现的?死锁有什么问题以及如何解决?

Pz.*_*Pz. 29

通常,死锁意味着两个或多个实体阻止某些源,并且它们都不能完成,因为它们是以循环方式阻塞源.

一个例子:假设我有表A和表B,我需要在A中进行一些更新然后B我决定在使用时锁定它们(这是非常愚蠢的行为,但它现在用于它的目的) .在同一时刻,其他人以相反的顺序做同样的事情 - 首先锁定B,然后锁定A.

按时间顺序,会发生这种情况:

proc1:锁定一个proc2:锁定B.

proc1:锁定B - 开始等待直到proc2释放B proc2:锁定A - 开始等待直到proc1释放A

很明显他们都不会完成.那是僵局.

洞更深入,但这只是入口,如果你需要了解更多,请花时间.在我们的大学里有关于这一点的全部讲座 - 所以不要认为阅读一些文章会让你成为专家;-)


Vla*_*cea 16

什么是死锁

当两个并发事务无法进行时,就会发生死锁,因为每个事务都在等待另一个事务释放锁,如下图所示。

僵局

由于两个事务都处于锁获取阶段,因此在获取下一个锁之前,它们都不会释放锁。

从僵局中恢复

如果您使用依赖于锁的并发控制算法,那么总是存在在死锁情况下运行的风险。死锁可能发生在任何并发环境中,而不仅仅是在数据库系统中。

例如,如果两个或多个线程正在等待先前获取的锁,则多线程程序可能会死锁,因此没有线程可以取得任何进展。如果这种情况发生在 Java 应用程序中,JVM 不能只是强制线程停止执行并释放其锁。

即使Thread该类公开了一个stop方法,该方法自 Java 1.1 以来已被弃用,因为它可能导致对象在线程停止后处于不一致状态。相反,Java 定义了一个interrupt方法作为提示,因为被中断的线程可以简单地忽略中断并继续执行。

因此,Java 应用程序无法从死锁情况中恢复,应用程序开发人员有责任以永远不会发生死锁的方式对锁获取请求进行排序。

但是,数据库系统无法强制执行给定的锁获取顺序,因为无法预见某个事务将进一步获取哪些其他锁。保持锁顺序成为数据访问层的职责,数据库只能协助从死锁情况中恢复。

数据库引擎运行一个单独的进程,该进程扫描当前冲突图以查找锁等待周期(由死锁引起)。当检测到一个循环时,数据库引擎会选择一个事务并中止它,从而释放它的锁,以便另一个事务可以取得进展。

与 JVM 不同,数据库事务被设计为原子工作单元。因此,回滚使数据库处于一致状态。

死锁优先级

虽然数据库选择回滚被卡住的两个事务之一,但并不总是可以预测哪一个将被回滚。根据经验,数据库可能会选择以较低的回滚成本回滚事务。

甲骨文

根据Oracle 文档,检测到死锁的事务是其语句将被回滚的事务。

数据库服务器

SQL Server 允许您通过DEADLOCK_PRIORITY会话变量控制在死锁情况下哪个事务更有可能被回滚。

DEADLOCK_PRIORITY会话可以接受任何整数-10和10之间,或预先定义的值,例如LOW (-5)NORMAL (0)HIGH (5)

如果发生死锁,当前事务将回滚,除非其他事务具有较低的死锁优先级值。如果两个事务具有相同的优先级值,则 SQL Server 将回滚成本最低的事务。

PostgreSQL

文档中所述,PostgreSQL 不保证回滚哪个事务。

MySQL

MySQL 尝试回滚修改 leas 记录数的事务,因为释放较少的锁成本较低。


Pau*_*aul 8

当两个人需要多个资源来执行时,并且每个人都锁定了一些资源,就会发生死锁.这导致A不能在没有B的情况下执行,反之亦然.

假设我有人A和人B.他们都需要运行两行(Row1和Row2).

  • Person A锁定Row1并尝试获取Row2.
  • Person B锁定Row2并尝试获取Row1.

Person A无法运行,因为它需要Row2,Person B无法运行,因为它需要Row1.这两个人都无法执行,因为他们锁定了对方需要的东西,反之亦然.


减少死锁的一种合理简单方法是在所有复杂事务中,您应该以相同的顺序执行操作.换句话说,以相同的顺序访问Table1然后Table2.这将有助于减少发生的死锁数量.