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

深入 SQL Server 交易機制:並發控制、隔離等級與鎖定架構完整解析

     編輯:關於SqlServer

概述

交易 (Transaction) 是資料庫並發控制的核心單位,遵循 ACID 特性 (原子性、一致性、隔離性、持久性)。SQL Server 透過鎖定、版本儲存、記錄機制實現交易隔離,保護資料完整性同時最大化並發度。

並發存取的三大負面現象

現象說明發生條件
髒讀讀取到其他交易未提交的修改資料讀取交易未取得共享鎖 (S Lock),或隔離等級為 READ UNCOMMITTED
不可重複讀同一交易多次讀取同一資料列,結果不一致 (被其他交易修改/刪除)讀取交易釋放共享鎖後,寫入交易取得排他鎖 (X Lock) 修改
幻讀同一交易多次執行相同範圍查詢,回傳列數不同 (被其他交易插入/刪除)範圍查詢未鎖定間隙 (Gap),插入交易在間隙新增列

SQL Server 隔離等級與並發現象對照

隔離等級髒讀不可重複讀幻讀實作機制
READ UNCOMMITTED✅ 可能✅ 可能✅ 可能不取得共享鎖,直接讀取資料頁
READ COMMITTED (預設)❌ 防止✅ 可能✅ 可能讀取時取得瞬間共享鎖,讀完即釋放
REPEATABLE READ❌ 防止❌ 防止✅ 可能讀取時取得共享鎖,持有至交易結束
SNAPSHOT❌ 防止❌ 防止❌ 防止資料列版本控制 (Row Versioning),讀取不阻塞寫入
SERIALIZABLE❌ 防止❌ 防止❌ 防止範圍鎖 (Key-Range Lock),完全序列化存取

設定隔離等級

-- 交易層級
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;  -- 或 REPEATABLE READ, SNAPSHOT, SERIALIZABLE
BEGIN TRANSACTION;
  -- 交易邏輯
COMMIT;

-- 查詢層級 (僅影響該陳述式)
SELECT * FROM dbo.Orders WITH (NOLOCK);           -- 等同 READ UNCOMMITTED
SELECT * FROM dbo.Orders WITH (READCOMMITTED);    -- 明確指定
SELECT * FROM dbo.Orders WITH (REPEATABLEREAD);
SELECT * FROM dbo.Orders WITH (SERIALIZABLE);

啟用 SNAPSHOT 隔離 (資料庫層級)

-- 允許資料庫使用快照隔離 (需獨佔存取)
ALTER DATABASE MyDB SET ALLOW_SNAPSHOT_ISOLATION ON;

-- 啟用預設 READ COMMITTED 使用快照 (RCSI)
ALTER DATABASE MyDB SET READ_COMMITTED_SNAPSHOT ON;

RCSI 讓預設 READ COMMITTED 行為改為讀取版本存儲,大幅減少讀寫封鎖,適合高並發 OLTP 系統。

鎖定架構與相容性

主要鎖模式

  • 共享鎖 (S):讀取資料,相容 S、IS、UIX
  • 更新鎖 (U):預備修改,相容 S、IS,不相容 U、X、IX
  • 排他鎖 (X):修改資料,僅相容 IX (意圖排他)
  • 意圖鎖 (IS, IX, SIU, UIX, SIX):層級鎖定意圖,防止層級衝突
  • 結構修改鎖 (Sch-M):DDL 操作,獨佔資料表
  • 大量更新鎖 (BU):大量匯入 (BULK INSERT、BCP)

鎖相容性矩陣 (簡版)

既有鎖 \ 要求鎖SUXISIX
S✅✅❌✅❌
U✅❌❌✅❌
X❌❌❌❌❌
IS✅✅❌✅✅
IX❌❌❌✅✅

死結與活結

  • 死結:循環等待資源,SQL Server 自動偵測並選擇犧牲者 (依成本) 回滾,錯誤 1205
  • 活結:重試邏輯導致持續衝突,需應用層加入隨機延遲或指數退避

監控與診斷工具

-- 檢視目前鎖定
SELECT * FROM sys.dm_tran_locks;

-- 檢視正在等待的工作階段
SELECT * FROM sys.dm_os_waiting_tasks WHERE wait_type LIKE 'LCK%';

-- 活動監視器 / sp_who2 / sp_lock (舊版)
-- 擴展事件 (Extended Events) 捕獲 deadlock_graph

最佳實踐建議

  1. 縮短交易範圍:僅包含必要 DML,業務邏輯、外部呼叫移出交易
  2. 固定存取順序:多表操作時,所有交易遵循相同表/索引順序,減少死結
  3. 善用 RCSI:讀多寫少系統啟用 READ_COMMITTED_SNAPSHOT,大幅降低封鎖
  4. 避免長時間持有鎖:大批次更新分批提交,搭配 WAITFOR DELAY 釋放鎖
  5. 索引優化:精準索引減少掃描範圍,縮小鎖定粒度
  6. 應用層重試邏輯:捕獲 1205/3960 錯誤,指數退避重試 (最多 3-5 次)

進階主題:記憶體優化資料表 (In-Memory OLTP)

SQL Server 2014+ 引入無鎖架構,使用樂觀並發控制 (OCC) 與多版本並發控制 (MVCC),完全避免傳統鎖定爭用,適合極高並發熱點資料。交易隔離等級支援 SNAPSHOT、REPEATABLE READ、SERIALIZABLE (語義不同)。

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