鎖是多使用者資料庫環境中協調並發存取、保證資料一致性的核心機制。本文系統介紹 SQL Server 的鎖概念、鎖對象、三大鎖類型、程式設計師視角的樂觀/悲觀鎖、四大隔離級別與觀察工具。
鎖是對資源存取的限制。SQL Server 可鎖定以下層級對象 (由細到粗):
| 鎖類型 | 相容性 | 觸發場景 | 釋放時機 |
|---|---|---|---|
| 獨佔鎖 | 與所有鎖不相容 | INSERT/UPDATE/DELETE | 交易結束 (COMMIT/ROLLBACK) |
| 共享鎖 | 與 S、U 相容;與 X 不相容 | SELECT 讀取 | 讀取完成即釋放 (除非 HOLDLOCK/隔離級較高) |
| 更新鎖 | 與 S 相容;與 U、X 不相容 | UPDATE/DELETE 尋找階段 | 確定修改升級為 X 鎖,持有至交易結束 |
| 類型 | 核心思想 | 實現方式 | 優點 | 缺點 |
|---|---|---|---|---|
| 樂觀鎖 | 假設衝突稀少,提交時檢查 | 版本戳/時間戳/檢查和比對 | 無鎖開銷,高並發讀取效能佳 | 衝突時需重試,適用低衝突場景 |
| 悲觀鎖 | 假設衝突常見,先鎖後用 | SELECT ... FOR UPDATE / UPDLOCK / 鎖提示 | 強一致性,適合高衝突寫入 | 並發度低,易死鎖,鎖開銷大 |
SQL Server 預設行為偏悲觀 (自動加鎖),但可透過 `READ_COMMITTED_SNAPSHOT` 實現樂觀讀取。
隔離級別定義交易對其他交易修改的可見度,等同於鎖定行為的預設規則。
| 隔離級別 | 髒讀 | 不可重複讀 | 幻影讀 | 鎖行為特徵 |
|---|---|---|---|---|
| READ UNCOMMITTED | 允許 | 允許 | 允許 | 不發共享鎖 (相當 NOLOCK) |
| READ COMMITTED (預設) | 禁止 | 允許 | 允許 | 發共享鎖,讀完即釋放 |
| REPEATABLE READ | 禁止 | 禁止 | 允許 | 共享鎖持有至交易結束 |
| SERIALIZABLE | 禁止 | 禁止 | 禁止 | 範圍鎖 (Key-Range),最高隔離 |
SET TRANSACTION ISOLATION LEVEL READ COMMITTED; -- 或 READ UNCOMMITTED / REPEATABLE READ / SERIALIZABLE
也可在單一查詢用鎖提示覆寫:`SELECT * FROM T WITH (NOLOCK)` 等。

EXEC sp_lock [spid]; -- spid 可從 master.dbo.sysprocesses 查詢,省略則顯示所有鎖

SELECT
request_session_id AS SPID,
resource_type,
resource_description,
request_mode,
request_status,
OBJECT_NAME(resource_associated_entity_id) AS ObjectName
FROM sys.dm_tran_locks;
死鎖:多進程互相持有資源並請求對方資源,形成環狀等待。SQL Server 死鎖偵測器定期掃描,選擇「犧牲成本最低」的受害者回滾,回傳錯誤 1205。
理解鎖粒度、三大基礎鎖類型、隔離級別對應的鎖行為、觀察工具與死鎖防範原則,是撰寫高並發、高可靠資料庫應用的必修課。除本章 DML 更新外,尚可透過檢視表更新資料,詳見第 13 章「游標與檢視表」。