鎖定模式

Microsoft SQL Server Database Engine 使用可決定並行交易如何存取資源的各種鎖定模式來鎖定資源。

下表顯示 Database Engine 使用的資源鎖定模式。

鎖定模式

描述

共用 (S)

用於不變更或更新資料的讀取作業,例如 SELECT 陳述式。

更新 (U)

用於可更新的資源上。防止當多個工作階段正在讀取、鎖定及後來可能更新資源時發生常見的死結。

獨佔 (X)

用於資料修改動作,例如 INSERT、UPDATE 或 DELETE。確保不能對相同資源同時進行多重更新。

意圖

用來建立鎖定階層。意圖鎖定的類型為:意圖共用 (IS)、意圖獨佔 (IX) 與共用意圖獨佔 (SIX)。

結構描述

執行相依於資料表結構描述的作業時使用。結構描述鎖定的類型為:結構描述修改 (Sch-M) 與結構描述穩定性 (Sch-S)。

大量更新 (BU)

用於大量複製資料到資料表,且已指定 TABLOCK 提示時。

索引鍵範圍

當使用可序列化交易隔離等級時,保護查詢讀取的資料列範圍。確定其他交易無法插入資料列,這些資料列在查詢重新執行時可限定可序列化交易的查詢。

共用鎖定

共用 (S) 鎖定允許並行交易在封閉式 (Pessimistic) 並行控制之下讀取 (SELECT) 資源。如需詳細資訊,請參閱<並行控制類型>。當資源存在共用 (S) 鎖定時,任何交易都無法修改資料。除非交易隔離等級是設為可重複讀取或更高等級,或是使用鎖定提示來保持交易期間的共用 (S) 鎖定,否則讀取作業一完成就會釋放資源的共用 (S) 鎖定。

更新鎖定

更新 (U) 鎖定可防止常見的死結。在可重複讀取或可序列化交易中,交易在讀取資料時取得資源 (頁面或資料列) 的共用 (S) 鎖定,然後修改資料,此過程需要將鎖定轉換為獨佔 (X) 鎖定。如果兩筆交易取得某個資源的共用模式鎖定,然後嘗試同時更新資料,則其中一筆交易便會嘗試將鎖定轉換為獨佔 (X) 鎖定。這種「從共用模式到獨佔」的鎖定轉換必須等待,因為某一筆交易的獨佔鎖定與另一筆交易的共用模式鎖定並不相容,所以會發生鎖定等候。第二筆交易便嘗試取得更新時的獨佔 (X) 鎖定。由於兩筆交易都轉換成獨佔 (X) 鎖定,且兩者皆等候另一筆交易釋放其共用模式的鎖定,因此便發生死結。

為了避免這種潛在的死結問題,則使用更新 (U) 鎖定。一次只有一筆交易可以取得資源的更新 (U) 鎖定。交易如果修改資源,更新 (U) 鎖定便轉換為獨佔 (X) 鎖定。

獨佔鎖定

獨佔 (X) 鎖定防止並行交易存取某個資源。運用獨佔 (X) 鎖定,沒有其他交易可修改資料;只有使用 NOLOCK 提示或讀取未認可隔離等級,才能進行讀取作業。

資料修改陳述式 (例如 INSERT、UPDATE 和 DELETE) 結合了修改和讀取作業。陳述式先執行讀取作業來取得資料,再執行必要的修改作業。因此,資料修改陳述式通常會同時要求共用鎖定和獨佔鎖定。例如,UPDATE 陳述式可能基於與一個資料表的聯結來修改另一個資料表的資料列。在這個案例中,除了對已更新的資料列要求獨佔鎖定之外,UPDATE 陳述式還對聯結資料表中讀取的資料列要求共用鎖定。

意圖鎖定

Database Engine 使用意圖鎖定來保護,它把共用 (S) 鎖定或獨佔 (X) 鎖定放在鎖定階層中較低的資源上。意圖鎖定會稱作意圖鎖定,是因為它們是在較低層級的鎖定之前取得的,因此表示將鎖定放在較低層級的意圖。

意圖鎖定有兩個用途:

  • 防止其他交易修改較高層級的資源,而導致較低層級的鎖定失效。

  • 為了改進 Database Engine 偵測資料粒度較高層級的鎖定衝突的效率。

例如,在資料表內的頁面或資料列要求共用 (S) 鎖定之前,先在資料表層級要求共用意圖鎖定。在資料表層級上設定意圖鎖定讓另一筆交易無法後續取得包含該分頁之資料表的獨佔 (X) 鎖定。意圖鎖定可以提昇效能,因為 Database Engine 只會在資料表層級上檢查意圖鎖定,來判斷交易是否可安全地取得該資料表的鎖定。這種方式省略了必須檢查資料表的每個資料列或分頁的鎖定來判斷交易是否可以鎖定整個資料表的需求。

意圖鎖定包括意圖共用 (IS)、意圖獨佔 (IX) 與共用意圖獨佔 (SIX)。

鎖定模式

描述

意圖共用 (IS)

保護在階層較低位置的某些 (但不是全部) 資源上要求的或取得的共用鎖定。

意圖獨佔 (IX)

保護在階層較低位置的某些 (但不是全部) 資源上要求的或取得的獨佔鎖定。IX 是 IS 的超集,它也保護在較低層級資源要求的共用鎖定。

與意圖獨佔共用 (SIX)

保護對階層較低位置的所有資源要求的或取得的共用鎖定,以及對某些 (但非全部) 較低層級資源的意圖獨佔鎖定。在最上層的資源中允許同時發生的 IS 鎖定。例如,在資料表上取得 SIX 鎖定也會取得所修改頁面的意圖獨佔鎖定,以及所修改資料列的獨佔鎖定。每個資源一次只能有一個 SIX 鎖定以防止其他的交易更新資源,雖然其他的交易可藉由取得資料表層級的 IS 鎖定來讀取階層架構中位於較低層級的資源。

意圖更新 (IU)

保護對階層中較低的所有資源要求的或取得的更新鎖定。IU 鎖定只使用於頁面資源。如果發生更新作業,IU 鎖定會轉換成 IX 鎖定。

共用意圖更新 (SIU)

S 和 IU 鎖定的結合,這是個別取得這些鎖定又同時保留兩種鎖定的結果。例如,交易執行具有 PAGLOCK 提示的查詢,然後執行更新作業。具有 PAGLOCK 提示的查詢取得 S 鎖定,而更新作業則取得 IU 鎖定。

更新意圖獨佔 (UIX)

U 和 IX 鎖定的結合,這是個別取得這些鎖定又同時保留兩種鎖定的結果。

結構描述鎖定

Database Engine 是在資料表的資料定義語言 (DDL) 作業 (例如加入資料行或卸除資料表) 期間使用結構描述修改 (Sch-M) 鎖定。在保留期間,Sch-M 鎖定禁止資料表的並行存取。這表示 Sch-M 鎖定會封鎖所有外在作業,直到釋放鎖定為止。

有些資料操作語言 (DML) 作業 (例如資料表截斷) 使用 Sch-M 鎖定來防止並行作業存取受影響的資料表。

Database Engine 在編譯並執行查詢時,會使用結構描述穩定性 (Sch-S) 鎖定。Sch-S 鎖定並未封鎖任何交易式鎖定,包括獨佔 (X) 鎖定。因此,其他的交易在查詢編譯期間可以繼續執行,包括對資料表使用 X 鎖定的那些交易。不過,取得 Sch-M 鎖定的並行 DDL 作業和並行 DML 作業無法在資料表上執行。

大量更新鎖定

當大量複製資料到資料表,以及指定 TABLOCK 提示或使用 sp_tableoption 設定 table lock on bulk load 資料表選項時,使用Database Engine 可使用大量更新 (BU) 鎖定。大量更新 (BU) 鎖定允許多個執行緒將資料同時大量載入到相同資料表,同時禁止未大量載入資料的其他處理序存取該資料表。

索引鍵範圍鎖定

索引鍵範圍鎖定是在使用可序列化交易隔離等級時,保護 Transact-SQL 陳述式所讀取之記錄集內隱含包括的資料列範圍。索引鍵範圍鎖定可防止幽靈讀取。透過保護資料列之間的索引鍵範圍,也可防止某交易存取的記錄集內的幽靈插入或刪除。