【问题标题】:SQL Server deadlock - Fix neededSQL Server 死锁 - 需要修复
【发布时间】:2017-05-15 20:04:13
【问题描述】:

我是 SQL Server DBA 的新手,每天至少有一次我在使用 Merge 语句的 SQL Server 2012 服务器中遇到死锁问题。合并语句中没有使用NOLOCKUPDLOCKHOLDLOCK 之类的子句。这是一个多用户环境,Biztalk 读取 xml 并将数据保存到 SQL Server。

Biztalk 每分钟读取 300 条 xml 消息。由于它是生产服务器,因此我无法在不进行研究的情况下实现任何类似的东西,但是我对如何解决此问题一无所知。最近,我遇到了两条 xml 消息试图更新表中的数据并尝试使用相同的索引并出错的问题。谁能帮我解决这个问题?

【问题讨论】:

  • 如果你能得到一个可重现的案例,在重现它的同时运行 SQL 跟踪,确保跟踪所有的“死锁”事件。这可以为您提供有关死锁的确切 SQL 信息以及确切资源的信息。死锁几乎总是由一个线程先处理资源 A 然后 B,而另一个线程处理 B 然后 A。有时您可以添加或删除索引以消除死锁,但有时您需要修改代码以始终获取相同的资源订购。
  • 我进行了死锁跟踪并了解了问题所在。然而,死锁并不总是发生,而是经常发生在合并语句中,这让我很难做出任何决定。
  • 死锁图应该显示正在死锁的确切项目(例如,将标识特定索引的对象 ID)。那就是你需要开始的地方。会有一个非常大的 ID,您可以使用此 SQL 来准确解码它所指的内容:SELECT hobt_id, object_name(p.[object_id]), index_id FROM sys.partitions p WHERE hobt_id = 72057594060734464 - 替换为您的具体锁ID
  • 这个在dba.stackexchange.com上更合适吗?

标签: sql-server sql-server-2012 database-deadlocks sql-merge


【解决方案1】:

MERGE 的扫描阶段使用共享锁 (S) 执行,针对单个会话运行 MERGE 和并发会话运行 SELECT 的情况进行了优化。在多个并发 MERGE 语句的情况下,这可能会导致死锁或失败。

您应该在目标表上添加 HOLDLOCK 提示的解决方案。这与在 SELECT 上使用 UPDLOCK 的其他读取更新模式有点不一致。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-11
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多