问题描述:实验室项目中新建项目提交审核,提交时会同时触发两个ajax请求,两个ajax请求对同一张表中的同一行数据进行修改。这个时候就容易发生并发冲突。。捕捉到System.Data.Linq.ChangeConflictException HResult=-2146233088……的问题
问题分析:在正常运行状态下,Linq在运行时,会把数据库的数据缓存到实体对象中,这是一种理想化的情况,并且在更新时,Linq会默认把除更新字段外的所有字段,作为Update语句中的Where条件。但是,如果此时有另外的程序,在访问数据库,并修改数据库数据的时候。这个时候where就会匹配不到该行,所以出现此问题(找不到行或行已更改)。
解决方案:
代码如下:
public void Submit()
{
try
{
base.SubmitChanges();
}
catch (System.Data.Linq.ChangeConflictException ex)
{
//base.ChangeConflicts.ResolveAll(RefreshMode.KeepCurrentValues);
//用上面的方法路径可以正常保存,但是state不能正常保存
//base.ChangeConflicts.ResolveAll(RefreshMode.OverwriteCurrentValues);
//用上面的方法state可以正常保存,但是路径不能正常保存
base.ChangeConflicts.ResolveAll(RefreshMode.KeepChanges);
//用该方法,路径和、state都能正常保存
base.SubmitChanges();
}
}
两个ajax请求,分别对同一张表的同一行中的路径和state进行了修改,这个时候更新数据库肯定报错:
base.ChangeConflicts.ResolveAll(RefreshMode.KeepCurrentValues);
修改路径的ajax请求中,state对应的是未修改的,但是修改state的请求已经正常结束保存到数据库中,这个时候模型中的state和数据库中的state是不一致的,出现并发冲突。base.ChangeConflicts.ResolveAll(RefreshMode.KeepCurrentValues);虽然可以不报错正常运行,但是这种方法使用Linq缓存中实体对象的值,覆盖当前数据库中的值也就是state并没有更改(保持当前的值),所以这种方法不适用。
base.ChangeConflicts.ResolveAll(RefreshMode.OverwriteCurrentValues);
保持原来的更新,放弃了当前的值.。分析同上
base.ChangeConflicts.ResolveAll(RefreshMode.KeepChanges);
保存原来的值 有冲突的话保存当前版本。