本文系統闡述 SQL Server 鎖機制的核心原理、分類體系、粒度層次、持有時機、自訂控制與監控診斷,並提供大量實戰範例與最佳實務建議,幫助 DBA 與開發者徹底掌握並發控制。
鎖透過在一段時間內禁止特定操作,強制序列化衝突操作,從而保證隔離性與一致性。
| 鎖模式 | 縮寫 | 描述 | 典型場景 |
|---|---|---|---|
| 共享鎖 | S | 允許並發讀取,禁止修改 | SELECT |
| 更新鎖 | U | 預防死鎖,讀取階段允許共存,更新前轉 X | UPDATE 前置 |
| 排它鎖 | X | 獨佔資源,禁止任何其他存取 | INSERT/UPDATE/DELETE |
意向鎖表示「我打算在較低層級 (頁/列) 申請 S/X 鎖」,讓 SQL Server 只需檢查表級意向鎖即可判斷是否可對整表加鎖,避免掃描所有頁/列鎖。
| 意向鎖類型 | 縮寫 | 含義 |
|---|---|---|
| 意向共享 | IS | 意圖在子資源加 S 鎖 |
| 意向排它 | IX | 意圖在子資源加 X 鎖 (IS 的超集) |
| 共享意向排它 | SIX | 意圖讀取全部子資源 (S) + 修改部分子資源 (IX) |
Sch-M (結構修改,DDL 專用)、Sch-S (結構穩定,編譯查詢計劃時)BU,BULK INSERT ... WITH (TABLOCK) 時使用SQL Server 支援多層次鎖粒度,粒度越細並發度越高但開銷越大:
| 資源類型 | 描述 | ||
|---|---|---|---|
| RID | 列識別碼 (Heap 表單列鎖定) | ||
| KEY | 索引鍵值 (索引列鎖定,支援鍵範圍鎖) | ||
| PAGE | 8KB 資料/索引頁 | ||
| EXTENT | 8 頁組成的區塊 | ||
| TABLE | 整張表 (含所有索引) | ||
| DATABASE | 整個資料庫 |
| 隔離級別 | 共享鎖 (讀) 持有 | 排它鎖 (寫) 持有 | 幻讀防護 |
|---|---|---|---|
| READ UNCOMMITTED | 不加 S 鎖 (髒讀) | 交易結束 | 無 |
| READ COMMITTED (預設) | 讀完即釋放 | 交易結束 | 無 |
| REPEATABLE READ | 交易結束 | 交易結束 | 有 (鎖定讀取範圍) |
| SERIALIZABLE | 交易結束 + 鍵範圍鎖 | 交易結束 | 完全防護 |
| SNAPSHOT / RCSI | 版本存儲 (無 S 鎖) | 交易結束 | 寫寫衝突檢測 |
SET DEADLOCK_PRIORITY LOW/NORMAL/HIGH/@var,決定死鎖犧牲者SET LOCK_TIMEOUT 1800 (毫秒),超時自動取消陳述式回傳錯誤 1222SET TRANSACTION ISOLATION LEVEL ... 或查詢提示 WITH (READUNCOMMITTED) 等SELECT ... WITH (HOLDLOCK, ROWLOCK, UPDLOCK, TABLOCKX, NOLOCK...)EXEC sp_indexoption 'IndexName', 'DisAllowPageLocks', 'TRUE'EXEC sp_lock / SELECT * FROM sys.dm_tran_locks:檢視當前鎖狀態DBCC TRACEON(1204, -1) / 1222:死鎖資訊寫入錯誤日誌 (文字 / XML 格式)lock_deadlock、lock_escalation:生產環境輕量級監控COMMIT/ROLLBACKLOCK_TIMEOUT (建議 3-10 分鐘),避免進程無限期掛起TRY...CATCH 錯誤處理,檢查 @@ERROR/ERROR_NUMBER()-- 1. 鎖定單列 (需配合索引)
SELECT * FROM Orders WITH (ROWLOCK, UPDLOCK) WHERE OrderID = 1001;
-- 2. 表級共享鎖 (允許讀、阻擋寫)
SELECT * FROM ConfigTable WITH (HOLDLOCK, TABLOCK);
-- 3. 表級排它鎖 (阻擋所有其他存取)
SELECT * FROM LogTable WITH (TABLOCKX) WHERE 1=0;
-- 4. 跳過被鎖列 (適用佇列處理)
SELECT TOP 1 * FROM TaskQueue WITH (READPAST, ROWLOCK, UPDLOCK) WHERE Status=0;
透過 sp_getapplock / sp_releaseapplock 實現邏輯層面的互斥,不鎖定實體資料資源,適用於跨表、跨資料庫甚至分散式協調場景。
| 提示 | 效果 | 等效隔離級別 |
|---|---|---|
| HOLDLOCK | 持有 S 鎖至交易結束 | SERIALIZABLE |
| NOLOCK | 不發出 S 鎖,允許髒讀 | READ UNCOMMITTED |
| PAGLOCK | 使用頁鎖而非表鎖 | - |
| READPAST | 跳過被鎖列 | READ UNCOMMITTED (僅 RID) |
| ROWLOCK | 強制列級鎖 | - |
| TABLOCKX | 強制表級 X 鎖 | - |
| UPDLOCK | 讀取時加 U 鎖而非 S 鎖 | - |
關鍵區別:WITH (HOLDLOCK) 允許其他讀取;WITH (TABLOCKX) 完全封鎖表,連讀取也阻擋。