| 術語 | 說明 |
|---|---|
| 並發 | 多使用者同時更新同一資料列 |
| 並發衝突 | 多使用者提交衝突值 |
| 開放式並發控制 | 提交前檢查資料是否被他人修改,假設衝突機率低 |
| 衝突解決 | 重新查詢、協調差異、決定保留或覆蓋 |
衝突發生條件:
UpdateCheck 的欄位)自上次讀取後已變更// 其他使用者先更新並提交
NorthwindDataContext other = new NorthwindDataContext();
var p = other.Products.First(x => x.ProductID == 1);
p.UnitPrice = 999.99M;
other.SubmitChanges();
// 當前使用者讀取最新值並更新
var product = db.Products.First(x => x.ProductID == 1);
product.UnitPrice = 777.77M;
db.SubmitChanges(); // 成功,無例外
var product = db.Products.First(x => x.ProductID == 1); // 讀取
// 其他使用者更新並提交
NorthwindDataContext other = new NorthwindDataContext();
var p = other.Products.First(x => x.ProductID == 1);
p.UnitPrice = 999.99M;
other.SubmitChanges();
// 當前使用者嘗試提交
product.UnitPrice = 777.77M;
try { db.SubmitChanges(); }
catch (ChangeConflictException) { /* 發生衝突 */ }
db.Transaction = sqlTransaction,自行 Commit/Rollback。TransactionScope,LINQ to SQL 偵測到環境交易自動加入,不關閉連線。SubmitChanges 內部自動建立本地交易,全部成功才提交,否則回滾。try {
Product p1 = db.Products.First(x => x.ProductID == 4);
Product p2 = db.Products.First(x => x.ProductID == 5);
p1.UnitsInStock -= 3;
p2.UnitsInStock -= 5; // 違反 CHECK 約束
db.SubmitChanges(); // 整批回滾
} catch (SqlException e) { /* 處理 */ }
using (TransactionScope ts = new TransactionScope()) {
try {
Product p1 = db.Products.First(x => x.ProductID == 4);
Product p2 = db.Products.First(x => x.ProductID == 5);
p1.UnitsInStock -= 3;
p2.UnitsInStock -= 5;
db.SubmitChanges();
ts.Complete();
} catch (SqlException e) { /* 處理 */ }
}