WITH (NOLOCK) 不僅自身不加鎖,也不會被現有鎖阻擋,可直接讀取被鎖定的資料列 (髒讀)。
| 提示 | 鎖類型 | 行為特性 | 適用場景 | 限制 |
|---|---|---|---|---|
NOLOCK | 無鎖 (READUNCOMMITTED) | 不加鎖、不被鎖阻擋、髒讀 | 報表查詢、近似統計、唯讀分析 | 僅限 SELECT |
HOLDLOCK | 保持鎖 (SERIALIZABLE 等價) | 持有共享鎖至交易結束、防止幻讀 | 需交易一致性的 SELECT | SELECT/UPDATE/DELETE 皆可 |
UPDLOCK | 更新鎖 | 讀取時加更新鎖、防止死鎖、允許其他共享鎖 | 「查詢後更新」模式 | SELECT/UPDATE/DELETE 皆可 |
XLOCK | 排他鎖 | 讀取時加排他鎖、完全阻擋其他存取 | 需獨佔資料的修改前查詢 | SELECT/UPDATE/DELETE 皆可 |
-- 錯誤示範
UPDATE dbo.test WITH (NOLOCK) SET username = 'wokofo';
-- 錯誤訊息:INSERT、UPDATE、DELETE 或 MERGE 語句的目標表不允許使用 NOLOCK 和 READUNCOMMITTED 鎖提示。
-- 唯讀報表:髒讀可接受,極致效能
SELECT TOP 10 * FROM dbo.test WITH (NOLOCK);
-- 需一致性快照:防止幻讀
SELECT TOP 10 * FROM dbo.test WITH (HOLDLOCK);
-- 查詢後立即更新:防止死鎖
SELECT TOP 10 * FROM dbo.test WITH (UPDLOCK);
UPDATE dbo.test WITH (UPDLOCK) SET username = 'wokofo' WHERE id = 1;
-- 獨佔存取:維護窗口操作
SELECT TOP 10 * FROM dbo.test WITH (XLOCK);
UPDATE dbo.test WITH (XLOCK) SET username = 'wokofo' WHERE id = 1;
READPAST - 跳過被鎖定的資料列 (佇列處理常用)ROWLOCK/PAGLOCK/TABLOCK - 強制鎖定粒度NOWAIT - 遇鎖立即報錯不等待