交易是資料庫一致性的基石。本文系統闡述交易的定義、ACID 四大特性、四種隔離等級 (Read Uncommitted 到 Serializable)、鎖定與封鎖關係、死鎖成因、常用 T-SQL 管理語法 (BEGIN/COMMIT/ROLLBACK/SAVE TRANSACTION) 與巢狀交易行為,並附上隔離等級選擇決策表,助你設計正確且高併發的資料庫操作邏輯。
SELECT/INSERT/UPDATE/DELETE)。BEGIN TRANSACTION 開啟,COMMIT 或 ROLLBACK 結束。| 特性 | 英文 | 核心定義 | 實現機制 |
|---|---|---|---|
| 原子性 | Atomicity | 全做或全不做,無中間狀態 | 記錄檔 + 復原管理員 (Undo/Redo) |
| 一致性 | Consistency | 交易前後資料庫滿足所有完整性約束 (PK, FK, CHECK, Trigger) | 約束驗證 + 觸發器 + 應用層邏輯 |
| 隔離性 | Isolation | 並發交易互不干擾,看不到彼此未認可的中間狀態 | 鎖定 (Lock) + 版本存儲 (Row Versioning) |
| 耐久性 | Durability | 認可後永久生效,不因系統故障遺失 | Write-Ahead Logging (WAL) + 檢查點 |
-- 開啟交易
BEGIN TRANSACTION [tran_name | @tran_name_var] [WITH MARK ['description']];
-- 認可交易 (寫入記錄檔認可標記,釋放鎖)
COMMIT TRANSACTION [tran_name | @tran_name_var];
-- 回滾交易 (撤銷所有操作,釋放鎖)
ROLLBACK TRANSACTION [tran_name | @tran_name_var | savepoint_name];
-- 設定儲存點 (支援部分回滾)
SAVE TRANSACTION savepoint_name;
-- 範例:巢狀交易與儲存點
BEGIN TRAN T1;
INSERT INTO T1 VALUES (1);
SAVE TRANSACTION SP1;
BEGIN TRAN T2; -- 實際上只是計數器 +1,不建立新交易
INSERT INTO T2 VALUES (2);
ROLLBACK TRANSACTION SP1; -- 僅回滾到 SP1,T1 的 INSERT 保留
COMMIT TRANSACTION T2;
COMMIT TRANSACTION T1;
關鍵規則:
• @@TRANCOUNT 遞增/遞減追蹤巢狀層級,只有最外層 COMMIT 真正寫入認可。
• ROLLBACK 無參數時回滾至最外層 BEGIN,@@TRANCOUNT 歸零。
• SAVE TRANSACTION 僅標記點,不影響 @@TRANCOUNT。
| 等級 | 別名 | 髒讀 | 不可重複讀 | 虛讀 | 鎖定策略 | 適用場景 |
|---|---|---|---|---|---|---|
| Read Uncommitted | 未授權讀取 | ✅ 允許 | ✅ 允許 | ✅ 允許 | 排他寫鎖 (Sch-S) | 報表/查詢容忍髒資料、極高併發 |
| Read Committed | 授權讀取 (預設) | ❌ 禁止 | ✅ 允許 | ✅ 允許 | 瞬間共享讀鎖 + 排他寫鎖 | 一般 OLTP,平衡一致性與併發 |
| Repeatable Read | 可重複讀取 | ❌ 禁止 | ❌ 禁止 | ✅ 允許 | 共享讀鎖持有至交易結束 + 排他寫鎖 | 需穩定讀取集合的報表/批次 |
| Serializable | 可序列化 | ❌ 禁止 | ❌ 禁止 | ❌ 禁止 | 範圍鎖 (Key-Range) 防止 Phantom | 極高一致性需求 (金融結算)、低併發 |
Read Committed 行為改為讀取版本存儲,讀不阻寫、寫不阻讀,無髒讀。ALTER DATABASE db SET READ_COMMITTED_SNAPSHOT ON / ALLOW_SNAPSHOT_ISOLATION ON (需單用戶模式)。成因:交易 A 鎖資源 1 等資源 2,交易 B 鎖資源 2 等資源 1,形成循環等待。
預防原則:
READ UNCOMMITTED (NOLOCK) 減少共享鎖持有。| 業務需求 | 建議等級 | 設定方式 |
|---|---|---|
| 高併發查詢、容忍臨時不一致 | READ UNCOMMITTED / NOLOCK | SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED 或 WITH(NOLOCK) |
| 標準 OLTP、預設行為 | READ COMMITTED | 無需設定 (預設) 或開啟 RCSI |
| 報表/批次需穩定讀取集合 | REPEATABLE READ | SET TRANSACTION ISOLATION LEVEL REPEATABLE READ |
| 金融結算/庫存扣款、零容忍 Phantom | SERIALIZABLE | SET TRANSACTION ISOLATION LEVEL SERIALIZABLE |
| 高併發寫入、需樂觀併發 | SNAPSHOT | 資料庫啟用 ALLOW_SNAPSHOT_ISOLATION + SET TRANSACTION ISOLATION LEVEL SNAPSHOT |
深入理解交易與隔離機制,能讓你在一致性與併發性的天平上做出精準權衡,寫出既正確又高效的資料庫程式碼。