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

LINQ to SQL 交易與樂觀並發衝突處理完整指南

     編輯:關於.NET

LINQ to SQL 採用樂觀並發機制處理資料衝突。提交更新時比對資料庫目前值與查詢時原始值,相同則提交,不同則拋出 ChangeConflictException 待開發者決定處理策略。

樂觀並發檢測原理

執行 UPDATE/DELETE 時,WHERE 子句包含主鍵 + 所有欄位原始值:

UPDATE [Customers] SET [CompanyName] = @p10
WHERE ([CustomerID] = @p0) AND ([CompanyName] = @p1) ... -- 參數為原始值
-- @@ROWCOUNT = 0 表示資料已被他人修改 → 拋出 ChangeConflictException

可透過 ColumnAttribute.UpdateCheck、IsVersion、IsPrimaryKey 控制檢測欄位,減少 WHERE 條件長度。

同一 DataContext 內不會衝突

var customerA = context.Customers.First();
var customerB = context.Customers.Where(c => c.CustomerID == customerA.CustomerID).Single();
customerA == customerB; // true,身分識別快取返回同一實例
customerA.CompanyName = "A";
customerB.CompanyName = "B";
context.SubmitChanges(); // 不衝突,最終值為 "B"

跨 DataContext 衝突範例與處理

var contextA = GenerateContext();
var contextB = GenerateContext(); // 模擬另一用戶
var customerA = contextA.Customers.First();
customerA.CompanyName = "From A";
var customerB = contextB.Customers.Where(c => c.CustomerID == customerA.CustomerID).Single();
customerB.CompanyName = "From B";
contextB.SubmitChanges(); // 先提交
try {
    contextA.SubmitChanges(); // 拋出 ChangeConflictException
} catch (ChangeConflictException) {
    // 處理衝突
}

衝突解決模式

DataContext.ChangeConflicts.ResolveAll(RefreshMode) 三種模式:

  • KeepCurrentValues:保留目前值,重新讀取資料庫值作為新原始值
  • OverwriteCurrentValues:以資料庫值覆寫目前值
  • KeepChanges:嘗試合併變更(僅衝突欄位以資料庫值覆寫)

交易控制

隱式交易(預設)

SubmitChanges() 自動建立交易,任一操作失敗整體回滾。

ConflictMode 參數

模式行為適用場景
FailOnFirstConflict(預設)遇衝突即停止並回滾需交易完整性(如銷售+庫存)
ContinueOnConflict記錄所有衝突繼續執行,最後拋出彙總異常批次日誌寫入等無強一致性需求

顯式交易控制

// ADO.NET 風格
context.Transaction = context.Connection.BeginTransaction();
try { context.SubmitChanges(); context.Transaction.Commit(); }
catch { context.Transaction.Rollback(); }

// TransactionScope 風格(推薦)
using (var scope = new TransactionScope()) {
    context.SubmitChanges();
    scope.Complete();
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved