首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SELECT 語句鎖定提示 (Table Hints) 完整指南:NOLOCK、HOLDLOCK、UPDLOCK、TABLOCK...

     編輯:關於SqlServer

為何需要鎖定提示?

SQL Server 預設隔離等級為 READ COMMITTED,透過共享鎖 (S) 保護讀取、排他鎖 (X) 保護寫入。但在特定業務場景 (報表唯讀、長交易一致性、避免死鎖、強制序列化) 需覆寫預設行為,SELECT ... FROM Table WITH (Hint) 即為此而生。

六大常用鎖定提示詳細解析

提示全名鎖類型與持有期典型用途風險/副作用
NOLOCK不加鎖 / READUNCOMMITTED不取得共享鎖,讀取未認可資料 (髒讀)報表查詢、資料探勘、可容忍不一致的大量掃描髒讀、非重複讀、幻讀、可能讀到中斷交易的半寫入頁面 (601/602 錯誤)
HOLDLOCK保持鎖 / SERIALIZABLE共享鎖持有至交易結束 (等同 SET TRANSACTION ISOLATION LEVEL SERIALIZABLE)需在交易內多次讀取同一資料且要求完全一致 (如庫存扣款前複查)並發度極低、易造成封鎖/死鎖、索引範圍鎖 (Key-Range Lock) 開銷大
UPDLOCK更新鎖讀取時取得更新鎖 (U),持有至交易/陳述式結束,轉 X 鎖時無衝突「查詢-修改」模式:先讀取再決定是否更新,避免轉換死鎖 (S→X 衝突)降低並發、若未真正更新仍持有 U 鎖較久
TABLOCK表鎖 (共享)整張表共享鎖,持有至陳述式結束大量載入前鎖定、報表需穩定快照且表較小封鎖所有寫入、大表嚴重影響並發
PAGLOCK頁鎖 (共享)共享頁鎖 (預設行為之一)明確指定頁級粒度,避免升級為表鎖較少直接指定,通常由最佳化器決定
TABLOCKX排他表鎖整張表排他鎖 (X),持有至交易/陳述式結束大量刪除/截斷前、DDL 維護窗口、單工模式匯入完全封鎖所有存取、極高風險,僅限維護窗口

進階提示與組合

  • READPAST:跳過已鎖定列/頁,適用佇列處理 (如 DELETE TOP (100) FROM Queue WITH (READPAST) OUTPUT deleted.*)。
  • ROWLOCK / PAGLOCK / TABLOCK:強制鎖粒度,配合 UPDLOCK/HOLDLOCK 使用。
  • INDEX(index_name)、FORCESEEK:存取路徑提示,非鎖定提示但常搭配使用。

關鍵限制與最佳實踐

  1. 覆寫隔離等級:提示優先於 SET TRANSACTION ISOLATION LEVEL,但 NOLOCK 不影響寫入鎖。
  2. 不可濫用 NOLOCK:財務、庫存、計價等核心業務嚴禁;僅限分析型、可重跑、可容忍錯誤的查詢。
  3. 避免 HOLDLOCK + 大範圍掃描:會產生大量 Key-Range Lock,導致嚴重封鎖;改用 SNAPSHOT 隔離等級 (RCSI) 取得陳述式/交易層級一致性且不封鎖寫入。
  4. 測試鎖升級:sys.dm_tran_locks 觀察鎖升級 (Lock Escalation) 行為,必要時 ALTER TABLE ... SET (LOCK_ESCALATION = DISABLE/AUTO)。
  5. 文件化業務理由:每個提示在程式碼註解說明 為何需要、預期並發影響、替代方案評估,避免「貼上去就不管」。

現代替代方案:資料列版本控制 (RCSI / SI)


-- 資料庫層級啟用 Read Committed Snapshot Isolation (RCSI)
ALTER DATABASE Db SET READ_COMMITTED_SNAPSHOT ON;

-- 或交易層級 Snapshot Isolation (SI)
ALTER DATABASE Db SET ALLOW_SNAPSHOT_ISOLATION ON;
SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
BEGIN TRAN; SELECT ...; COMMIT;

RCSI 讓 READ COMMITTED 讀取透過 tempdb 版本存儲取得一致性快照,**完全不取得共享鎖,寫入不封鎖讀取,讀取不封鎖寫入**,解決 90% 過去需 NOLOCK/HOLDLOCK 的場景,且無髒讀風險。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved