在並發控制場景中,有時需要手動鎖定資料表以進行維護、資料修正或防止髒讀。本文整理 SQL Server 中常用的表級鎖定語法、查詢被鎖資源的 DMV 查詢,以及透過系統預存程序 sp_lock 進行強制解鎖的完整流程。
SELECT * FROM YourTable WITH (HOLDLOCK);
SELECT * FROM YourTable WITH (TABLOCKX);
利用 sys.dm_tran_locks 即時檢視物件層級鎖定:
SELECT
request_session_id AS spid,
OBJECT_NAME(resource_associated_entity_id) AS tableName
FROM sys.dm_tran_locks
WHERE resource_type = 'OBJECT';
spid:持有鎖定的工作階段 ID。tableName:被鎖定的資料表名稱。當必須強制釋放鎖定時,建議遵循以下四步驟:
CREATE TABLE #HarveyLock (
SPID INT, DBID INT, OBJID INT, INDID INT,
TYPE VARCHAR(100), RESOURCE VARCHAR(100),
MODE VARCHAR(100), STATUS VARCHAR(100)
);
INSERT INTO #HarveyLock EXEC sp_lock;
SELECT * FROM #HarveyLock
WHERE OBJID = OBJECT_ID('YourTable') -- 依資料表過濾
AND MODE IN ('X', 'IX', 'S', 'U'); -- 常見鎖模式
DECLARE @spid INT = 57; -- 取自上一步查詢結果 DECLARE @sql VARCHAR(1000) = 'KILL ' + CAST(@spid AS VARCHAR); EXEC(@sql);
ALTER TABLE ... SET (LOCK_ESCALATION = DISABLE) 可在資料表層級停用(需評估並發影響)。sys.dm_exec_requests 的 blocking_session_id、wait_type、wait_time 可建立完整阻塞鏈視圖。| Hint | 鎖類型 | 相容性 | 典型用途 |
|---|---|---|---|
| HOLDLOCK | Range-S / Serializable | 相容 S,不相容 X/U | 長交易一致性讀取 |
| TABLOCKX | Table X | 完全排他 | 大量匯入、DDL 維護 |
| TABLOCK | Table S | 相容 S,不相容 X | 掃描大表時減少鎖升級 |
| UPDLOCK | Update (U) | 相容 S,不相容 U/X | 讀取後即更新,防止死結 |
| XLOCK | Exclusive (X) | 完全排他 | 讀取即獨佔,極少使用 |
| NOLOCK / READUNCOMMITTED | 無鎖 (髒讀) | 不獲取共享鎖 | 報表查詢容忍髒讀 |
掌握上述工具與流程,即能在生產環境中快速定位、處理資料表鎖定爭用問題,保障系統穩定運行。