在上一篇文章中提到了并发冲突,还说详细的说明在这讲来说,呵呵,那现在就说一下吧!
并发冲突产生的原因
事实上,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客户端修改的值了。