Sql-Server

UPDATE 會導致 SQL SERVER 中的死鎖嗎?

  • February 11, 2021

如果同時執行相同的更新查詢,我們會遇到死鎖嗎?

假設有一個包含數百萬條記錄的表,我們需要一次更新數千條記錄。

UPDATE TABLEX
SET Column1 = '1'
WHERE Column2 BETWEEN 1 AND 10000

我想知道並發執行此查詢是否會導致死鎖,因為每個更新查詢可能會以不同的順序獲取行上的更新鎖。

換句話說,以下是一種可能的情況。場景是兩個並發會話執行相同的查詢來更新同一組記錄。

(我的假設是每個 UPDATE 語句都會以不同的順序掃描行)

  1. 會話 1:獲取第 1 行的更新鎖(Column2 = 1)
  2. 會話 2:獲取第 2 行的更新鎖(Column2 = 2)
  3. 會話 1:嘗試獲取第 2 行的更新鎖,但由於會話 2 已經持有它而失敗。(Column2 = 2)
  4. 會話 2:嘗試獲取第 1 行的更新鎖,但由於會話 1 已經持有它而失敗。(Column2 = 1)
  5. 檢測到死鎖。

在這裡,我的假設是每個查詢可能以不同的順序掃描行,這意味著對行(資源)的鎖定將以不同的順序進行。這會導致僵局嗎?

在這裡,我的假設是每個查詢可能以不同的順序掃描行,這意味著對行(資源)的鎖定將以不同的順序進行。

正如您所概述的那樣,這種情況在正常情況下不太可能發生。同時執行的完全相同的查詢很可能使用相同的執行計劃——這意味著它們都將以TABLEX相同的順序掃描索引。這種情況很可能會導致兩個相同查詢之間的阻塞而不是死鎖。

這假設您有一個索引Column2,可用於尋找正確的位置,然後掃描需要更新的行子集。

如果您在 上沒有索引Column2,則最終可能會並行掃描索引/表,因此您的更新可能是不確定的順序。考慮這樣的計劃:

並行更新計劃截圖

來自聚集索引掃描的行的順序將根據計劃使用的核心數量、每個核心執行其他工作的繁忙程度以及與磁碟相關的等待等類似情況而有所不同。除非“收集流”是保持順序的,否則行將以一種隨機順序更新。正如您所描述的,這可能會導致死鎖。

總之,您的問題的答案取決於幾個因素,包括表/索引的詳細資訊、隔離級別、伺服器和數據庫級別設置等。希望這能讓您對所涉及的內容有所了解。

引用自:https://dba.stackexchange.com/questions/285180