在上一篇文章中提到了併發衝突,還說詳細的說明在這講來說,呵呵,那現在就說一下吧!
併發衝突產生的原因
事實上,linq to sql中的併發衝突是指記錄在進行update操作時,客戶端A1取出的資料{1,zzl,male},客戶端A2也取出這條資料{1,zzl,male},這時A1進行對實體重新賦值{1,zzl,female},並進行submit提交,資料庫的值被改為{1,zzl,female}
注意:這時資料庫的值{1,zzl,female}與A2所取出的值{1,zzl,male}已經不相同了,這時,在進行update時就會出現併發衝突。
併發衝突的應對
在進行submitchange時,由於產生了併發異常,這時.net會丟擲System.Data.Linq.ChangeConflictException異常,我們可以把它進行捕捉,然後根據我們的要求,去重新進行資料上下文的提交,事實上,程式碼部分已經在上一篇文章中給出,這裡,再寫一遍
public void SaveChanges() { ChangeSet cSet = _db.GetChangeSet(); if ((cSet.Inserts.Count > 0 || cSet.Updates.Count > 0 || cSet.Deletes.Count > 0) && !UnitOfWork.IsNotSubmit) { try { UnitOfWork.SaveChanges(); } catch (System.Data.Linq.ChangeConflictException) { foreach (System.Data.Linq.ObjectChangeConflict occ in _db.ChangeConflicts) { // 使用當前資料庫中的值,覆蓋Linq快取中實體物件的值 occ.Resolve(System.Data.Linq.RefreshMode.OverwriteCurrentValues); } UnitOfWork.SaveChanges(); } catch (Exception)//如果出現異常,就從資料字典中清除這個鍵值對 { DbFactory.ClearContextByThread(System.Threading.Thread.CurrentThread, _db); } } }
我們可以看到,資料上下文的ChangeConflicts屬性用來獲取所有成員的併發衝突,這時,它所有衝突遍歷後,然後進行Resove 將衝突進行解決,最後再把上下文提交到資料庫覆蓋掉原來的{1,zzl,female},資料庫中最後儲存的內容將是A2客戶端修改的值了。