【问题标题】:Update same rows simultaneously different columns. DeadLock同时更新相同的行不同的列。僵局
【发布时间】:2018-08-01 19:32:15
【问题描述】:

在我的 Javascript 代码中,我调用 3 simultaneos WebMethods。

网络方法 1

UPDATE MyTable
    SET ColA = 'Val1'
WHERE Condition1 = 'X'
AND Condition2 = 'Y'

WebMethod 2

UPDATE MyTable
    SET ColB = 'Val2'
WHERE Condition1 = 'X'
AND Condition2 = 'Y'

WebMethod 3

UPDATE MyTable
    SET ColC = 'Val3'
WHERE Condition1 = 'X'
AND Condition2 = 'Y'

我的表

正如预期的那样,即使我在更新语句中使用WITH (ROWLOCK),我也会遇到死锁

如何告诉 SqlServer 锁定行但允许读取其他更新。

因为死锁在以下情况下消失:

UPDATE MyTable
    SET ColA = 'Val1'
WHERE ID IN
(
    SELECT ID
    FROM MyTable WITH(READUNCOMMITTED)
    WHERE Condition1 = 'X'
    AND Condition2 = 'Y'
)

【问题讨论】:

  • 有人可能会问为什么要调用 3 个方法来同时更新同一行的不同列。似乎单个更新会更有意义。或者这只是现实世界锁定的一个例子?
  • 这只是一个例子,因为在现实世界中,我有多个用户更新同一列,而不是相同的 javascript。

标签: sql-server database-deadlocks


【解决方案1】:

“懒惰”的最佳方法是不要这样做(了解它可能不好的原因!)是将WITH(NOLOCK) 添加到您的SELECT 语句中:

SELECT ID
FROM MyTable WITH(NOLOCK)
WHERE Condition1 = 'X'
AND Condition2 = 'Y'

NOLOCK 可能导致脏读,并返回不完整的数据。更好的选择是使用READPAST,这完全取决于您要做什么。

理想情况下,您希望只使用 1 条语句运行所有更新,但也许只是您做了一个简单的示例 :) 它引发死锁是有充分理由的,您可以按顺序进行每个调用。

如果您想在没有 SELECT 的情况下执行 SQL,您可以尝试使用 UPDATE MyTable WITH (ROWLOCK),但请记住,这只是一个提示,不能保证。

【讨论】:

  • NOLOCK 是一种糟糕的处理方式。作为更新的一部分,它可以做一些非常棒的事情,比如损坏的索引。请不要建议人们将 NOLOCK 用于此类事情。他们可能不知道更好,实际上会听从您的建议。如需更深入地了解 NOLOCK 的“功能”,请查看此处。 blogs.sentryone.com/aaronbertrand/bad-habits-nolock-everywhere
  • 我很清楚危险,因此发出警告。我不认为我会将它用于生产代码。我可能应该更多地强调危险。
  • 我知道使用 NOLOCK 的危险。如果我使用 WITH (ROWLOCK),死锁仍然会出现。总是。
  • 嗯...知道真正的危险也许不建议使用危险的方法会更谨慎。 ;) 但也许您只是指其他选择语句,而不是更新,在这种情况下,规避锁定是一种常见的(尽管并非没有问题)。
【解决方案2】:

一种方法是查找表是否被锁定,然后做相应的事情。

if not exists(SELECT
OBJECT_NAME(p.OBJECT_ID) AS TableName,
resource_type, resource_description
FROM
sys.dm_tran_locks l
JOIN sys.partitions p ON l.resource_associated_entity_id = p.hobt_id
where OBJECT_NAME(p.OBJECT_ID)='MyTable')
Begin

Update Sql
End
else
begin
-- Table is lock
insert the info in another table.

Later run any Job and update the table.
end

另一种方式,

在 Ajax 本身中处理并发问题。

AjaxQueue1AjaxQueue2

所以谷歌搜索类似的东西。

【讨论】:

    猜你喜欢
    • 2015-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多