C# 为什么会引发第二个DatabaseConflictException?

C# 为什么会引发第二个DatabaseConflictException?,c#,.net,linq-to-sql,concurrency,C#,.net,Linq To Sql,Concurrency,我有一些linq2sql的东西更新了一些行。 然后,当我提交时,我会这样做: try { database.SubmitChanges(); } catch (ChangeConflictException) { database.ChangeConflicts.ResolveAll(RefreshMode.KeepChanges); database.SubmitChanges(); } 现在,第二次提交(catch中的提交)再次抛出一个ChangeConflictE

我有一些linq2sql的东西更新了一些行。 然后,当我提交时,我会这样做:

try
{
    database.SubmitChanges();
}
catch (ChangeConflictException)
{
    database.ChangeConflicts.ResolveAll(RefreshMode.KeepChanges);
    database.SubmitChanges();
}
现在,第二次提交(catch中的提交)再次抛出一个ChangeConflictException

这怎么可能?如果可能的话。人们需要如何进行查询?(我不能再试一次了,我什么时候能停下来?)

我只希望将更改后的值放入数据库中

编辑: 让我重新表述一下这个问题的意图:当我说‘ResolveALL(keepchanges)’时,我会认为我说的是:“我不在乎……只使用我的价值观。”。相反,它再次抛出相同的异常

我对这种行为感到惊讶,因为MSDN上的示例在第二次提交更改时没有第二次尝试

那么,这些异常可以抛出多少次(与列的次数相同?),并且我可以以某种方式避免它们(在说ResolveAll之后)

编辑: 开始赏金前的最后一次编辑:

我已经按照其中一位评论者的建议,将它变成了一个整洁的循环。但我重试多少次并不重要。从它开始抛出异常的那一刻起,它将永远不会在没有异常的情况下这样做!所以,要么它第一次起作用,要么根本不起作用

现在我的linq更新中有大约20或50行需要更新(我使用批处理来加快速度)。 每个resolveall是否仅修复一列或一行中的一个问题?或者,它是否足够聪明,可以修复遇到的所有问题

总而言之:我刚刚更改的值(只有1或2列)是需要进入数据库的值,无论发生什么。如何使用linq实现这一点(或者我真的应该为此打开SqlConnection吗?(如果是,为什么首先使用linq?)

我的代码到现在为止:

 int retry;
 for (retry = 0; retry < 10; retry++)
 {
      try
      {
           database.SubmitChanges();
           //submit succeeded... break loop
           break;
      }
      catch (ChangeConflictException)
      {
           database.ChangeConflicts.ResolveAll(RefreshMode.KeepChanges);

           if (retry > 0)
           {
                Thread.Sleep(retry * 10);  //introduce some wait, to see if this helps
           }
      }
int重试;
对于(重试=0;重试<10;重试++)
{
尝试
{
database.SubmitChanges();
//提交成功…中断循环
打破
}
捕获(ChangeConflictException)
{
database.changepconflicts.ResolveAll(RefreshMode.KeepChanges);
如果(重试>0)
{
Sleep(重试*10);//引入一些wait,看看这是否有帮助
}
}
编辑:找到了

多亏了接受答案中的博客链接,我现在循环浏览所有冲突并记录下来,看看是什么导致了这一点

我很高兴我这么做了,因为事实证明,其中一个DB字段包含一个触发器,它在某些情况下会更新其他内容。因此,我可以随心所欲地解决问题,每次触发器再次触发时,都会引发下一次冲突


这个触发器显然我没有意识到关闭,因为我的DB管理员把它放在那里跟踪某个东西或其他东西。触发器可能是一个很好的工具,但如果你没有意识到它们,它们可能会引起很大的麻烦!

如果这是你需要不断重试的事情,那么明显的代码重新排序是:

bool success = false;
while (!success)
{
  try
  {
    database.SubmitChanges();
    success = true;
  }
  catch (ChangeConflictException)
  {
    database.ChangeConflicts.ResolveAll(RefreshMode.KeepChanges);
  }
}

我对数据库了解不多,所以我不会对您的实际问题进行理论分析,但也许这会解决它://

当您调用SubmitChanges()时,它可能不会发现您的所有冲突(因此不会全部解决),因为默认行为是在到达第一个冲突时停止

试着改变

database.SubmitChanges();


有关更多信息,请参阅。他还在ResolveAll()的代码示例中嵌套了两个级别的try/catch,因此第二次提交更改()尝试后,他可以在退出之前记录任何异常。这似乎是一个合理的模型。

谢谢……但我仍然不确定为什么会发生异常。我已经指定:好的,是的,请解决所有问题。为什么1毫秒后它会给出完全相同的异常。谁知道这可能会不确定地继续。尝试在没有k的情况下解决保留更改?你的系统中有什么样的并发性?我不想使用这个循环,因为它可能是无限的——我宁愿尝试X次后失败,也不愿永远失败,如果有无法解决的问题……如果函数被称为“ResolveAll”,并且它们在技术上确实做到了这一点,那就太好了,但是它们真的不像w这是别人期望的。我将尝试这种方法,看看是否可以解决。运气不好。相同的行为。=^(我将更深入地阅读博客,并按照他们的建议为我感兴趣的列设置UpdateCheck列属性。在我链接的页面上,它还显示了一种通过循环冲突来解决冲突的方法(并调用resolve()我怀疑这两种方法都依赖于Linq在您尝试解决冲突之前已经识别了所有冲突。这听起来不像ResolveAll()强制使用暴力(正如您所说,“我不在乎,只使用我的值”)更改数据库,但它会处理通过调用SubmitChanges()建立的ChangeConflictCollection中的每一项。另一个想法…请参见下面链接中的代码示例。在调用Resolve()之后,似乎不需要再次调用SubmitChanges()。幸运的是,这个函数的文档非常清晰:(不是)。无论如何,在他的第一个示例中,您的第一篇博客文章在解决更改后再次提交更改
database.SubmitChanges(ConflictMode.ContinueOnConflict);