C# 并发冲突解决方案

问题描述:实验室项目中新建项目提交审核,提交时会同时触发两个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);
保存原来的值 有冲突的话保存当前版本。

猜你喜欢

转载自blog.csdn.net/weixin_42706227/article/details/81625322