無鎖 = 十字路口無號誌,資料不一致(髒讀、不可重複讀、幻讀);鎖太狠 = 全紅燈,併發效能為零。SQL Server 鎖管理器在「資料一致性」與「併發效能」間動態平衡。
| 維度 | 類型 | 說明 |
|---|---|---|
| 模式 | 共享鎖 (S) | 讀取資料,相容 S/IS,不相容 X/U |
| 更新鎖 (U) | 預備更新,防止死鎖,僅相容 S/IS | |
| 排他鎖 (X) | 修改資料,獨佔,不相容任何鎖 | |
| 意圖鎖 (IS/IX/IU) | 表示下層有鎖,允許上層快速檢查 | |
| 結構鎖 (Sch-S/Sch-M) | DDL 操作專用 | |
| 大量更新鎖 (BU) | 大量插入優化 | |
| 轉換鎖 (SIX/SIU/UIX) | 混合模式 | |
| 鍵範圍鎖 | 可序列化隔離等級專用 | |
| 應用程式鎖 | sp_getapplock 自定義 | |
| 粒度 | 資料庫、檔案、資料表、堆/索引、頁、鍵/列、區、應用、中繼資料 | 越細併發越高,記憶體/CPU 開銷越大 |
注意:臨界值非固定,SQL Server 依系統負載動態調整。
ALTER TABLE dbo.Test SET (LOCK_ESCALATION = AUTO | TABLE | DISABLE)
AUTO(預設):分區表升級到分區層級,非分區表升級到表級TABLE:直接升級到表級DISABLE:禁用升級(謹慎使用,可能導致記憶體耗盡)WITH (TABLOCK)、WITH (PAGLOCK) 強制粗粒度鎖CREATE DATABASE TestLock;
CREATE TABLE dbo.Test (
ID INT IDENTITY(1,1) PRIMARY KEY,
Name VARCHAR(50) NOT NULL DEFAULT '',
CreatedTime DATETIME NOT NULL DEFAULT GETDATE()
);
-- 插入 30 萬筆測試資料
WHILE 1=1 INSERT INTO dbo.Test(Name) VALUES('kk');
sys.dm_tran_locks 查看目前鎖狀態UPDATE dbo.Test SET Name = 'name' WHERE Name = 'kk';Lock:Escalation,鎖從 KEY (X) → OBJECT (X)-- 插入階段
Database (S) ×3, Page (IX), Object (IX), Key (X) ×2
-- 更新初期
Key (X) 大量增加
-- 觸發升級瞬間
Object (X) 出現,Schema (Sch-S) 保護中繼資料
-- 升級完成
僅保留 Object (X),釋放所有 Key (X) 與 Sch-S
sys.dm_os_waiting_tasks 與 sys.dm_tran_locks 定位阻塞鏈