2009-12-15 107 views
1

我有一些linq2sql的东西,它更新了一些行。 后来,当我提出我这样做:为什么第二个DatabaseConflictException被抛出?

try 
{ 
    database.SubmitChanges(); 
} 
catch (ChangeConflictException) 
{ 
    database.ChangeConflicts.ResolveAll(RefreshMode.KeepChanges); 
    database.SubmitChanges(); 
} 

现在第二个提交(一个在catch)被再次抛出ChangeConflictException

这怎么可能?如果可能的话。如何需要查询? (我不能再放一个围绕那个的尝试/捕捉?我什么时候会停下来?)

我只想将更改后的值放入数据库中。

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

我对这种行为感到惊讶,因为MSDN上的例子不具有围绕第二的SubmitChanges

那么多少次这些异常被抛出第二次尝试捕捉(如因为有列多少次?) ,我可以完全避免它们(在说完ResolveAll之后)?

编辑: 最后编辑之前,我开始赏金:

我已经把它做成一个整洁的循环由评论者1的建议。但重试多少次并不重要。一旦它开始抛出异常,它将永远不会发生异常!所以无论它是第一次运作,还是根本行不通。

现在我的linq更新有20或50行需要更新(我使用批处理来加快速度)。 每一个决心都只能解决1列1列中的一个问题吗?还是足够聪明,可以解决遇到的所有问题?

回顾一下:我刚刚更改的值(只有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 
      } 
     } 

编辑:找到了!

感谢链接到博客中公认的答案我现在循环所有冲突并记录他们看到的是什么原因造成这一点。

而且我很高兴我做到了,因为它事实证明,其中一个数据库字段包含一个触发器,它会更新别的我在某些条件下。所以我可以尽我所能地解决,每次触发器会再次触发,导致下一次冲突。

这个触发器显然没有意识到,因为我的数据库管理员把它放在那里去追踪某些东西或其他东西。触发器可以是一个很好的工具,但是如果你不知道它们,它们会导致严重的头痛!

回答

2

它可能不是在所有的冲突,当你调用的SubmitChanges(被捡)(并因此不解决这些问题全部),因为默认的行为是停止时,它达到第一个。

尝试改变

database.SubmitChanges(); 

database.SubmitChanges(ConflictMode.ContinueOnConflict); 

更多信息,请参见http://arun-ts.blogspot.com/2009/08/linq-to-sql-concurrency-conflicts.html。他还在其ResolveAll()的代码示例中嵌套了两层try/catch,因此第二次尝试SubmitChanges()时,他可以在退出之前记录任何异常。这似乎是一个合理的模式。

+0

伟大的,如果功能被称为“ResolveAll”他们实际上在技​​术上做到这一点,但他们真的不相信某人的期望。我会尝试这种方法,看看这是否解决它。 – Toad 2010-01-25 17:41:53

+0

没有运气。同样的行为。 = ^(我会阅读博客更深入和我感兴趣的是,他们建议列设置UpdateCheck的列属性。 – Toad 2010-01-25 17:53:25

+0

在我链接到网页,这也说明通过冲突循环的方法解决它们(并在每个方法上调用Resolve())我怀疑这两种方法都依赖于Linq在你试图解决它们之前确实已经确定了所有的冲突,听起来不像ResolveAll()那样强制使用暴力(正如你所说的“我不在乎,只要用我的价值观”)改变到数据库,而是需要照顾每一个项目的建成通过调用的SubmitChanges()的ChangeConflictCollection。 – 2010-01-25 17:54:33

0

如果这是你需要不断重试的东西,那么代码的一个明显的重新排序是:

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

我不很了解数据库,所以我会从理论化什么远离你实际的问题是,但也许这将修复它:/

+0

感谢......我真不知道,虽然,为什么例外保持发生。我已经指定:好的,请解决所有请。那么为什么在1毫秒后它给出了完全相同的例外。谁知道这可能会无限期地继续下去。 – Toad 2009-12-15 22:07:35

+0

尝试解决而不保持更改? – Martin 2009-12-15 22:09:24

+0

你的系统中正在进行什么类型的并发? – Martin 2009-12-15 22:17:45

相关问题