交易處理將一組資料庫操作合併為單一邏輯工作單元,確保所有操作要麼全部成功提交,要麼全部回滾,維護資料一致性與完整性。典型案例為銀行轉帳:扣款與存入必須同時完成,不可僅執行一方。
SQL 使用兩條簡單陳述式控制交易:
BEGIN TRANSACTION:啟動交易,後續所有命令納入交易範圍。COMMIT TRANSACTION:提交交易,使所有變更永久生效。若發生錯誤,可執行 ROLLBACK TRANSACTION 撤銷所有未提交變更。
核心類別為 System.Data.SqlClient.SqlTransaction(OLE DB 對應 OleDbTransaction)。主要屬性與方法:
| 屬性/方法 | 說明 |
|---|---|
| Connection | 關聯的 SqlConnection 物件 |
| IsolationLevel | 定義交易隔離等級(列舉值見下表) |
| Commit() | 提交交易 |
| Rollback() | 回滾交易(僅限未提交狀態) |
| Save(savepointName) | 建立儲存點,可部分回滾 |
| 值 | 行為描述 |
|---|---|
| Chaos | 高度獨立交易的暫存變更不可被覆寫 |
| ReadCommitted | 共享鎖定讀取,資料可在交易結束前更新,可能發生不可重複讀或幻影資料(預設值) |
| ReadUncommitted | 允許髒讀,不發出共享鎖定也不接受獨佔鎖定 |
| RepeatableRead | 鎖定查詢使用的所有資料,防止其他使用者更新,但仍可能出現幻影列 |
| Serializable | 範圍鎖定,防止其他使用者在交易完成前更新或插入列(最嚴格等級) |
using System;
using System.Data.SqlClient;
class TransactionDemo
{
static void Main()
{
string connStr = "Data Source=.;Initial Catalog=Northwind;Integrated Security=True";
using (SqlConnection conn = new SqlConnection(connStr))
{
conn.Open();
SqlTransaction tx = conn.BeginTransaction(); // 1. 啟動交易,取得交易參考
SqlCommand cmd = conn.CreateCommand();
cmd.Transaction = tx; // 2. 將命令關聯至交易
try
{
cmd.CommandText = "INSERT INTO Categories (CategoryName) VALUES ('Test1')";
cmd.ExecuteNonQuery();
cmd.CommandText = "INSERT INTO Categories (CategoryName) VALUES ('Test2')";
cmd.ExecuteNonQuery();
tx.Commit(); // 3. 全部成功則提交
Console.WriteLine("交易提交成功");
}
catch (Exception ex)
{
tx.Rollback(); // 4. 發生錯誤則回滾
Console.WriteLine("交易回滾: " + ex.Message);
}
}
}
}
關鍵步驟:BeginTransaction() 標記交易起始,回傳的 SqlTransaction 參考需指派給所有參與交易的 Command.Transaction 屬性。最後視執行結果呼叫 Commit() 或 Rollback()。