【问题标题】:Update deadlock issue更新死锁问题
【发布时间】:2015-03-29 04:28:50
【问题描述】:

我正在使用 SQL Server 2005 并遇到了死锁问题。我已经开始阅读 NO LOCK,但我不确定这是解决我的问题的正确方法。任何帮助将不胜感激。

我有一个每 15 秒运行一次的批处理。它根据外键列表生成动态 UPDATE SQL 语句。为了过于简化,想象一下下面的简单 SQL 语句:

UPDATE dual
SET val1 = @val1
WHERE fk = @fk
;

请记住,这个示例过于简化,对于每个外键,SQL 语句实际上是不同的,但它更新的表和值始终相同。我不能只写一个更新语句来一次处理所有外键。

如果我一次运行每个语句,一切正常,但我冒着超过 15 秒间隔的风险。作为一个灵丹妙药,我决定对批处理应用程序进行多线程处理,这样它就可以一次运行 25 个更新语句,而不是一次只运行 1 个。完成此操作后,我开始收到死锁错误。

如何解决这个死锁问题?记住三件事:

  1. 批处理是唯一会插入、更新或 从相关表中删除记录
  2. 每个 UPDATE 语句都使用 WHERE 子句中的外键,所以 该批次永远不会一次访问相同的记录
  3. 如果记录获得错误数据,批次将在 下次运行

【问题讨论】:

  • 您要记住的 3 件事:#1 似乎不太可能。我敢打赌,在某个地方还有另一个进程参与了僵局。如果您可以捕获死锁图,那么为您指明正确的方向将非常有帮助。 Creating a SQL Server Agent Alert by Using the WMI Provider for Server Events
  • 每条正在运行的更新语句更新了多少行?超过5000?我假设所有“FK”列都已编入索引?
  • 贴出代表UPDATE的执行计划和死锁图。

标签: sql-server sql-server-2005


【解决方案1】:

代替您当前的设置,在您的动态 sql 中创建一个表变量并将您的值插入其中。这将全部是插入,因此您不必担心死锁。接下来通过将表变量连接到真实表来更新表。这样,您只需使用一条更新语句即可访问实际表。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-27
    • 1970-01-01
    • 2011-03-28
    • 2012-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-31
    相关资源
    最近更新 更多