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

學習 Linq to SQL (七):樂觀平行存取與交易處理

     編輯:關於.NET

偵測平行存取衝突

Linq to SQL 預設採 樂觀平行存取:更新時比對原始值,若資料庫已被修改則拋出 ChangeConflictException。可在 [Column] 設定 UpdateCheck=UpdateCheck.Never 忽略特定欄位檢查。

解決衝突三種模式

try {
  ctx.SubmitChanges(ConflictMode.ContinueOnConflict);
}
catch (ChangeConflictException) {
  foreach (var cc in ctx.ChangeConflicts) {
    var p = (Product)cc.Object;
    // 1. OverwriteCurrentValues:放棄本地修改,以資料庫值為準
    // cc.Resolve(RefreshMode.OverwriteCurrentValues);
    // 2. KeepCurrentValues:放棄資料庫修改,以本地值為準
    // cc.Resolve(RefreshMode.KeepCurrentValues);
    // 3. KeepChanges (預設):合併非衝突欄位,衝突欄位以本地值為準
    cc.Resolve(RefreshMode.KeepChanges);
  }
  ctx.SubmitChanges();
}

欄位級衝突處理

foreach (var cc in ctx.ChangeConflicts) {
  foreach (var mc in cc.MemberConflicts) {
    if (mc.Member.Name == "UnitsInStock") mc.Resolve(RefreshMode.KeepCurrentValues);
    else if (mc.Member.Name == "UnitPrice") mc.Resolve(RefreshMode.OverwriteCurrentValues);
    else mc.Resolve(RefreshMode.KeepChanges);
  }
}

ConflictMode 選項

  • ContinueOnConflict:嘗試處理所有衝突,最後統一解決。
  • FailOnFirstConflict:遇到第一個衝突即停止,不繼續處理後續。

交易處理

預設隱性交易

SubmitChanges() 內部自動開啟交易,任一操作失敗整批回滾。

顯性 DbTransaction

if (ctx.Connection.State != ConnectionState.Open) ctx.Connection.Open();
var tran = ctx.Connection.BeginTransaction();
ctx.Transaction = tran;
try {
  CreateCustomer(new Customer { CustomerID="abcdf", CompanyName="zhuye" });
  CreateCustomer(new Customer { CustomerID="abcde", CompanyName="zhuye" }); // 重複 PK 失敗
  tran.Commit();
} catch { tran.Rollback(); }

TransactionScope (建議)

using (var scope = new TransactionScope()) {
  CreateCustomer(new Customer { CustomerID="abcdf", CompanyName="zhuye" });
  CreateCustomer(new Customer { CustomerID="abcde", CompanyName="zhuye" });
  scope.Complete();
}

支援分散式交易,程式碼更簡潔。

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