【问题标题】:SQL Server - Deadlock on clustered indexSQL Server - 聚集索引死锁
【发布时间】:2019-02-23 10:53:59
【问题描述】:

我有一个表 A,主键上有一个聚集索引,第二列 (act_id) 有一个非聚集索引(表 B 的外键)

两个更新语句正在生成以下死锁: Deadlock 1

这个死锁似乎不是书签查找死锁,因为它在同一个索引和同一个 objid 上。在非聚集索引中包含 pk 并没有带来任何成功。 我确实明白,objid 不是recordid,而是索引中的一个范围。

导致此死锁的查询(例如,更新一组 act_id = 1,其中 act_id = 2)具有以下执行计划: Execution plan

有时相同的死锁出现在另一个只有一个聚集索引的表上:Same deadlock on another table

有人知道如何避免这种僵局吗?

【问题讨论】:

  • 您的交易中有多个语句吗?你能发布整个事务的 SQL 吗?

标签: sql-server deadlock clustered-index non-clustered-index


【解决方案1】:

感谢您的回答。 我画了一张图更清楚:

我们有任务,它们有一个动作。每个动作可以有多个参数。 我们的应用程序包含多个部署。每个部署都可以上传这些任务。 在示例中,我有三个部署。 2 个插件和一个基本模块。 2 个插件一直在等待基础模块准备好,然后两个模块都在自己的事务中调用基础模块中的 .upload() 。在某一时刻,任务将被更新(如果有变化)。因此,两个插件中的任务都发生了变化,这会产生死锁。

【讨论】:

    【解决方案2】:

    这两个查询似乎都在更新聚集索引的 B 树的同一部分。 这个并发问题有多种答案。一种是获得更快的硬件。另一个是没有可以更改的主键。

    我首先要问你:你是从 2 个单独的查询中更新你的主键吗?
    你有天然钥匙吗?
    您是否在主键/外键上设置了级联更新?
    您的其他阻止查询是什么?

    在非聚集索引中包含pk并没有带来任何成功

    那是因为 pk 总是在所有非聚集索引中,否则它会如何进行书签查找?

    【讨论】:

    • 他正在更改非PK专栏。通常,U 锁可以防止简单的单行更新的多种死锁。例如,PK 对同一行的并发更新永远不会死锁。在这方面,我不确定通过非 PK 列的更新。
    • 两个查询属于同一类(更新A set act_id where act_id = XX),每个act_id可能有不止一行
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-01
    • 2018-05-08
    • 2018-01-02
    • 2014-12-21
    • 2010-11-23
    • 2014-04-27
    相关资源
    最近更新 更多