| 問題 | 說明 | 範例 |
| 髒讀 | 讀取未提交資料 | 交易 1 修改列,交易 2 讀取;交易 1 回滾 → 交易 2 讀到不存在的資料 |
| 不可重複讀 | 同一交易多次讀取同列,結果不同 | 交易 1 讀取 → 交易 2 修改並提交 → 交易 1 再讀,值已變 |
| 幻讀 | 範圍查詢前後筆數不同 | 交易 1 查詢某範圍 → 交易 2 插入新列 → 交易 1 再查,多出幻影列 |
SQL Server 四大隔離等級對比
| 隔離等級 | 髒讀 | 不可重複讀 | 幻讀 | 並發度 | 一致性 |
| Read Uncommitted | 是 | 是 | 是 | 最高 | 最低 |
| Read Committed | 否 | 是 | 是 | 高 | 中 |
| Repeatable Read | 否 | 否 | 是 | 中 | 高 |
| Serializable | 否 | 否 | 否 | 最低 | 最高 |
.NET System.Data.IsolationLevel 枚舉對應
| 成員 | 對應 SQL Server | 行為說明 |
ReadUncommitted | Read Uncommitted | 允許髒讀,不發共享鎖,不接受獨佔鎖 |
ReadCommitted | Read Committed | 讀取時保持共享鎖防髒讀,但提交前資料可被改(預設值) |
RepeatableRead | Repeatable Read | 查詢範圍加鎖防不可重複讀,仍可能有幻讀 |
Serializable | Serializable | 範圍鎖防止插入/刪除,完全序列化 |
Snapshot | Snapshot (行版本) | 使用資料列版本控制,讀不阻寫、寫不阻讀 |
Chaos | - | 無法覆寫更高隔離等級的掛起變更 |
Unspecified | - | 使用非指定隔離等級,無法確定具體等級 |
動態調整隔離等級
交易執行中呼叫 transaction.IsolationLevel = IsolationLevel.Serializable; 即時生效,後續指令套用新等級。可依業務階段切換:查詢密集用 ReadCommitted,關鍵結帳用 Serializable。
效能與正確性取捨建議
- 預設
ReadCommitted 適合大多數 OLTP 場景。
- 報表、匯總查詢可考慮
Snapshot 避免鎖定衝突。
- 庫存扣款、金融轉帳等強一致性場景用
Serializable 或應用層樂觀鎖。
- 避免長交易持有高等級鎖,導致封鎖與死鎖風險上升。
適用範圍說明
本文針對 System.Data.SqlClient (SQL Server);若使用 OleDb、Odbc 或其他 Provider,行為細節可能不同,請參考對應文件。
- 上一篇文章: Windows Forms 控制項開發:擴充 TreeView 資料繫結與 CurrencyManager 同步(四)
- 下一篇文章: C# 資料庫交易實務(五):儲存點機制與部分回滾實作
Copyright ©
程式碼之家 All Rights Reserved