同时更新同一行的不同列。僵局

时间:2018-08-01 19:32:16

标签: sql-server database-deadlocks

在我的Javascript代码中,我称3个simultaneos WebMethods。

WebMethod 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'

MyTable

enter image description here

按预期,即使在更新语句中使用WITH (ROWLOCK),我也会获得DeadLock

enter image description here

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

因为在以下情况下,DeadLock消失了:

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

2 个答案:

答案 0 :(得分:0)

“懒惰”和最好不要这样做的方法(理解它可能很糟糕的原因!)是在您的WITH(NOLOCK)语句中添加SELECT

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

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

理想情况下,您只想让更新全部使用1条语句运行,但也许只是您举了一个简单的例子:)它有一个很好的理由引发死锁,您可以按顺序进行每个调用。

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

答案 1 :(得分:0)

一种方法是查找表是否为锁,然后相应地执行操作。

create table #test (test_id int, test_name nvarchar(64))

insert into #test (test_id, test_name) values (1, 'Jonn Doe')

create synonym test for #test

select * from test

另一种方式,

处理Ajax本身的并发问题。

AjaxQueue1 AjaxQueue2

所以google类似的东西。