首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

LINQ to SQL 交易管理全攻略:三種建立交易模式與最佳實務

     編輯:關於.NET

交易 (Transaction) 是資料庫操作的原子單位,滿足 ACID 特性。LINQ to SQL 提供三種交易建立方式,本文系統化解析各模式適用場景與代碼範例。

模式一:預設隱式交易 (SubmitChanges 內建)


var ctx = new NorthwindDataContext();

var c1 = new Customer { CustomerID = "TESTA", CompanyName = "testa's company" };
var c2 = new Customer { CustomerID = "TESTBC", CompanyName = "testb's company" }; // ID 長度 6,超過 DB 限制 5

ctx.Customers.InsertOnSubmit(c1);
ctx.Customers.InsertOnSubmit(c2);

ctx.SubmitChanges(); // 內部自動開啟 ReadCommitted 交易
  • c2 違反 CHECK (LEN(CustomerID) <= 5) 約束 → 拋出 SqlException。
  • 交易自動回滾,**c1、c2 皆未寫入資料庫**。
  • 適用場景:單一 SubmitChanges() 即可完成的業務單元。

模式二:手動指定 DataContext.Transaction (自訂隔離等級)


var ctx = new NorthwindDataContext();

ctx.Transaction = ctx.Connection.BeginTransaction(IsolationLevel.Serializable);
try
{
    ctx.SubmitChanges();
    ctx.Transaction.Commit();
}
catch
{
    ctx.Transaction.Rollback();
    throw;
}
finally
{
    ctx.Transaction = null; // 釋放連線回連線池
}
  • 可控制 **隔離等級** (ReadCommitted / RepeatableRead / Serializable / Snapshot 等)。
  • 需手動 Commit/Rollback 並清空 ctx.Transaction,否則連線無法正確歸還連線池。
  • 適用場景:需調整隔離等級、或單一 DataContext 多次 SubmitChanges 需在同一交易中。

模式三:TransactionScope 環境交易 (推薦、支援分散式交易)


using (var scope = new TransactionScope())
{
    var ctx = new NorthwindDataContext();
    ctx.SubmitChanges();

    // 同一 Scope 內可跨多個 DataContext、甚至跨資料庫 (需 MSDTC)
    var ctx2 = new AnotherDataContext();
    ctx2.SubmitChanges();

    scope.Complete(); // 標記成功,離開 using 時自動 Commit
}
// 隱式 Rollback 若未呼叫 Complete()

進階用法:包含 ExecuteCommand 的混合操作


using (var scope = new TransactionScope())
{
    var ctx = new NorthwindDataContext();

    ctx.ExecuteCommand("EXEC sp_ComplexLogic1");
    ctx.ExecuteCommand("EXEC sp_ComplexLogic2");
    ctx.ExecuteCommand("EXEC sp_ComplexLogic3");

    ctx.SubmitChanges(); // 實體變更與 SP 執行在同一交易

    scope.Complete();
}
  • ExecuteCommand、SubmitChanges、多個 DataContext **自動登記** 至同一環境交易。
  • 若需跨資料庫/伺服器,確保啟用 **MSDTC (Distributed Transaction Coordinator)** 服務。
  • 預設隔離等級 Serializable,可透過 TransactionScopeOption、TransactionOptions 調整。

三種模式對照表

維度預設隱式DataContext.TransactionTransactionScope
程式碼複雜度最低 (零配置)中 (手動 Commit/Rollback)低 (using 區塊)
隔離等級控制固定 ReadCommitted完全可控可配置 (預設 Serializable)
跨 DataContext不支援不支援 (單一連線)支援 (環境交易)
跨資料庫/分散式不支援不支援支援 (需 MSDTC)
混合 ExecuteCommand不支援 (獨立交易)不支援支援
例外安全自動 Rollback需 try/finally自動 Rollback (using)
推薦場景簡單單一 SubmitChanges特殊隔離等級需求現代應用首選

常見陷阱與避坑指南

  1. 連線洩漏:手動模式未在 finally 設 ctx.Transaction = null,導致連線永佔不釋放。
  2. 巢狀 TransactionScope:預設 TransactionScopeOption.Required 會加入現有交易,若內層 Complete() 外層未 Complete(),整體仍回滾。
  3. 非同步/多執行緒:TransactionScope 預設 **不流動** 至其他執行緒 (需 TransactionScopeAsyncFlowOption.Enabled .NET 4.5.1+)。
  4. 資料庫鎖升級:Serializable 範圍鎖極易造成死鎖,高併發場景建議 ReadCommittedSnapshot (RCSI) + ReadCommitted。

總結

現代 LINQ to SQL 應用 **首選 TransactionScope**:語法簡潔、自動管理生命週期、支援跨 DataContext/資料庫、混合 ExecuteCommand。僅在需精細控制隔離等級或舊版 .NET 無 System.Transactions 時,考慮手動 DataContext.Transaction。預設隱式交易僅適合最簡單的單一 SubmitChanges 場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved