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

SQL Server 五大交易隔離等級實戰演示:髒讀、不可重複讀、幻讀完整複現

     編輯:關於SqlServer

交易隔離等級控制「一個交易如何影響其他交易、以及如何被其他交易影響」。本文以 READ UNCOMMITTED 為起點,逐級演示 髒讀、不可重複讀、幻讀 現象,並對應隔離等級解決方案。

測試環境建立

CREATE TABLE TranLevel (k INT IDENTITY(1,1), val INT);
INSERT INTO TranLevel(val) VALUES (1),(2),(3);

等級 1:READ UNCOMMITTED (最低隔離,最高並發)

現象:髒讀 (讀到未 Commit 資料) + 不可重複讀 (同一交易兩次讀取結果不同)。

-- Query 1 (Session 1)
BEGIN TRAN Q1;
UPDATE TranLevel SET val = 9; -- 不 Commit
WAITFOR DELAY '00:00:10';
ROLLBACK TRAN Q1;

-- Query 2 (Session 2)
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
BEGIN TRAN Q2;
SELECT 'Tx2 開始,讀到 Tx1 未 Commit 的 9' AS msg; SELECT * FROM TranLevel;
WAITFOR DELAY '00:00:10';
SELECT 'Tx1 已 Rollback,Tx2 再讀變回 1/2/3,不可重複讀' AS msg; SELECT * FROM TranLevel;
COMMIT TRAN Q2;
READ UNCOMMITTED 執行結果

等級 2:READ COMMITTED (預設)

  • 解決髒讀:只讀已 Commit 資料。
  • 仍存在不可重複讀、幻讀。
  • READ COMMITTED SNAPSHOT (RCSI):資料庫選項 READ_COMMITTED_SNAPSHOT ON,讀取行版本,完全避免讀寫阻塞,但需 TempDB 空間支撐版本存放區。

等級 3:REPEATABLE READ

  • 解決不可重複讀:交易期間鎖定已讀取資料列 (共享鎖持有至結束)。
  • 仍存在幻讀:新插入符合條件的列可被其他交易 Commit。

等級 4:SNAPSHOT (行版本化)

  • 需 ALLOW_SNAPSHOT_ISOLATION ON。
  • 讀取交易開始時的資料快照,完全無阻塞,解決髒讀、不可重複讀、幻讀。
  • 寫入衝突:若兩交易修改同一列,後 Commit 者失敗 (錯誤 3960),需應用重試。

等級 5:SERIALIZABLE (最高隔離)

  • 鎖定範圍 (Range Lock),防止幻讀,效能最差,並發最低。
  • 相當於 HOLDLOCK 提示。

隔離等級比較總表

選擇建議

  1. 預設 READ COMMITTED + 開啟 RCSI (資料庫層級),兼顧並發與一致性。
  2. 長跑報表查詢明確指定 SET TRANSACTION ISOLATION LEVEL SNAPSHOT。
  3. 極少數關鍵業務 (扣款、對帳) 使用 SERIALIZABLE 或 HOLDLOCK,並儘量縮短交易範圍。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
隔離等級髒讀不可重複讀幻讀並發度典型用途
READ UNCOMMITTED發生發生發生最高報表/近似查詢、臨時資料
READ COMMITTED防止發生發生高OLTP 預設
REPEATABLE READ防止防止發生中需穩定統計的報表
SNAPSHOT防止防止防止高 (讀不阻寫)高並發報表、長交易查詢
SERIALIZABLE防止防止防止最低金融對帳、庫存扣款關鍵區段