我有两个语句(对一个表(称为表 A)中的每一行的更新和在另一个表上查找表 A 中的行的删除),我知道这会导致偶尔的死锁。好像在表A的同一个主键索引上有一个X锁和一个U锁。
我一直在尝试复制 SQL Server Management Studio 中的死锁,但失败了。我应该可以吗?
另外,delete 语句效率非常低,我想我可以通过创建覆盖索引来解决这个问题,这意味着上面提到的主键索引不再包含在 delete 语句的实际执行计划中。鉴于最终两个语句都需要相同的行,这是否可以保证没有死锁,或者只是通过为 SQL Server 提供不同的数据路径来减少发生死锁的机会?
我终于设法得到一个死锁图,如下所示:
如果我没看错,右边的流程节点在 PK_LoanFacility 上有一个排他锁,并且正在请求另一个(也许这是因为在与这个流程节点关联的语句中有两个更新。第一个将一个字段设置为 NULL所有行,然后第二行使用从另一个数据库中提取的值更新子集)。左侧的流程节点在 PK_LoanFacility 上有一个更新锁,并且正在请求一个共享锁。左边的语句从子表中删除一行,并通过 WHERE 子句查找父 ID。即 DELETE FROM table where ForeignID = (SELECT ID FROM ParentTable WHERE x = y)。我不确定为什么这需要对 PK_LoanFacility(父表的 PK)进行更新锁定。我猜每当你从表中删除一行时,
如前所述,我相当确定我可以通过添加一些适当的索引来消除对所请求的共享锁的需要,但我仍然有兴趣了解正在发生的事情。