交易隔離等級控制「一個交易如何影響其他交易、以及如何被其他交易影響」。本文以 READ UNCOMMITTED 為起點,逐級演示 髒讀、不可重複讀、幻讀 現象,並對應隔離等級解決方案。
CREATE TABLE TranLevel (k INT IDENTITY(1,1), val INT);
INSERT INTO TranLevel(val) VALUES (1),(2),(3);
現象:髒讀 (讀到未 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_COMMITTED_SNAPSHOT ON,讀取行版本,完全避免讀寫阻塞,但需 TempDB 空間支撐版本存放區。ALLOW_SNAPSHOT_ISOLATION ON。HOLDLOCK 提示。| 隔離等級 | 髒讀 | 不可重複讀 | 幻讀 | 並發度 | 典型用途 |
|---|---|---|---|---|---|
| READ UNCOMMITTED | 發生 | 發生 | 發生 | 最高 | 報表/近似查詢、臨時資料 |
| READ COMMITTED | 防止 | 發生 | 發生 | 高 | OLTP 預設 |
| REPEATABLE READ | 防止 | 防止 | 發生 | 中 | 需穩定統計的報表 |
| SNAPSHOT | 防止 | 防止 | 防止 | 高 (讀不阻寫) | 高並發報表、長交易查詢 |
| SERIALIZABLE | 防止 | 防止 | 防止 | 最低 | 金融對帳、庫存扣款關鍵區段 |