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

SQL Server 交易隔離等級完整解析:五大模式、三大併發異常與選擇指南

     編輯:關於SqlServer

三大併發異常定義

異常發生情境後果
髒讀事務 A 讀取事務 B 修改但**未提交**的資料若 B 回滾,A 讀到的資料從未存在(無效值)
不可重複讀事務 A 兩次讀取同一列,期間事務 B **修改並提交**該列A 兩次讀到不同值,邏輯判斷失效
幻讀事務 A 兩次執行相同範圍查詢,期間事務 B **插入/刪除**符合條件的列A 兩次結果集筆數不同,出現/消失「幻影」列

五大隔離等級對照表

隔離等級髒讀不可重複讀幻讀鎖定機制並發度適用場景
READ UNCOMMITTED❌ 允許❌ 允許❌ 允許不加共享鎖(Sch-S 除外)最高近似即時報表、資料倉庫、可容忍髒資料
READ COMMITTED(預設)✅ 防止❌ 允許❌ 允許讀取時加共享鎖,讀完即釋放高一般 OLTP、大多數應用預設選擇
REPEATABLE READ✅ 防止✅ 防止❌ 允許讀取時加共享鎖,**持有至交易結束**中需一致性快照的報表、庫存扣款前檢查
SERIALIZABLE✅ 防止✅ 防止✅ 防止範圍鎖,防止插入/刪除幻影列低財務結帳、庫存配額嚴格控制
SNAPSHOT✅ 防止✅ 防止✅ 防止**列版本控制(行版本存 tempdb)**,讀不阻塞寫高(讀寫不阻塞)高並發讀寫混合、長時間報表查詢

SNAPSHOT 隔離的特殊機制

  • 啟用資料庫選項:ALTER DATABASE MyDB SET ALLOW_SNAPSHOT_ISOLATION ON;
  • 讀取時建立**交易開始時刻的資料快照**(複製到 tempdb 版本存放區),後續讀取皆基於此快照。
  • 寫入衝突偵測:若兩事務修改同一列,後提交者會收到錯誤 3960(更新衝突),需重試。
  • 不需範圍鎖即可防止幻讀,因快照固定了可見列集合。

設定隔離等級

-- 會話層級(影響後續交易)
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;   -- 預設
SET TRANSACTION ISOLATION LEVEL SNAPSHOT;

-- 單一查詢層級(Table Hint)
SELECT * FROM Orders WITH (READUNCOMMITTED);      -- NOLOCK 同義
SELECT * FROM Orders WITH (SNAPSHOT);             -- 需資料庫啟用 SNAPSHOT

-- 檢視目前隔離等級
DBCC USEROPTIONS;  -- 尋找 'isolation level' 行

選擇決策樹

  1. **能容忍髒讀嗎?** → 能 → READ UNCOMMITTED(極少數場景)。
  2. **需完全序列化一致性?** → 能 → SERIALIZABLE(鎖爭用高,慎用)。
  3. **高並發讀寫、長查詢不想被阻塞?** → SNAPSHOT(需評估 tempdb 壓力)。
  4. **一般 OLTP、需防髒讀即可?** → READ COMMITTED(預設,最平衡)。
  5. **同一交易多次讀同列需一致?** → REPEATABLE READ。

READ COMMITTED SNAPSHOT (RCSI) 變體

ALTER DATABASE MyDB SET READ_COMMITTED_SNAPSHOT ON;
啟用後,READ COMMITTED 行為變為**語句級快照**(非交易級),讀取不加共享鎖,防髒讀、不可重複讀、幻讀在**單一陳述式**層級自動防止。這是**現代高並發系統的推薦預設值**,無需修改應用程式碼即可獲得讀寫不阻塞優勢。

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