LINQ-to-SQL那點事~LINQ-to-SQL中的併發衝突與應對

張佔嶺發表於2013-06-19

回到目錄

上一篇文章中提到了併發衝突,還說詳細的說明在這講來說,呵呵,那現在就說一下吧!

併發衝突產生的原因

事實上,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客戶端修改的值了。

回到目錄

相關文章