【发布时间】:2021-02-11 04:33:48
【问题描述】:
同时运行相同的 UPDATE 查询会导致死锁吗?
假设有一个包含数百万条记录的表,我们需要一次更新数千条记录。
UPDATE TABLEX
SET Column1 = '1'
WHERE Column2 BETWEEN 1 AND 10000
我想知道并发运行此查询是否会导致死锁,因为每个更新查询可能会以不同的顺序获取页/行 U 锁。
换句话说,以下是一种可能的情况。场景是两个并发会话运行相同的查询来更新同一组记录。
- 会话 1:获取第 1 行的更新锁定(列 2 = 1)
- 会话 2:获取第 2 行的更新锁定(列 2 = 2)
- 会话 1:尝试获取第 2 行的更新锁,但失败,因为它已被会话 2 持有。(列 2 = 2)
- 会话 2:尝试获取第 1 行的更新锁,但失败,因为它已被会话 1 持有。(列 2 = 1)
- 检测到死锁。
在这里,我的假设是每个查询可能以不同的顺序扫描行,这意味着对行的锁定将以不同的顺序进行。
【问题讨论】:
-
只有当 2 个进程试图以相反的顺序获取 2 个锁时才会发生死锁。直接更新不会发生这种情况,因为它们以相同的顺序获取相同的锁。你为什么要同时运行 same 更新? PS 反引号是怎么回事 - 这不是有效的 SQL Server 吗?
-
好吧,如果您的查询可能相同?但是你为什么要运行 2 个相同的查询呢?从您的问题开始,您似乎正在同时更新 不同的 行?但后来你暗示相同的行 - 你能解释一下吗?
-
对于您提出的问题,这可能过于简单化了。在这种情况下,细节有很大的影响。例如,我无法想象您会在您的网络应用程序上意外地同时更新来自 2 个不同客户端的 1000 行。
-
@DaleK 行锁是每行的,例如,如果查询 1 按分配顺序访问聚集索引的 2 行,而查询 2 按键顺序访问它们,那么两个行锁之间可能会出现死锁。诚然,这不太可能发生。当您的 NCI 不涵盖查询并导致乱序键查找时,死锁的可能性更大
-
@DaleK 它可能会死锁,是的。但我同意你刚刚提出的所有其他观点。我有一个纯理论的、人为的论点,这不太可能发生。
标签: sql-server sql-update locking deadlock database-deadlocks