【发布时间】:2009-12-15 21:26:03
【问题描述】:
我有一些更新一些行的 linq2sql 东西。 然后,当我提交时,我会这样做:
try
{
database.SubmitChanges();
}
catch (ChangeConflictException)
{
database.ChangeConflicts.ResolveAll(RefreshMode.KeepChanges);
database.SubmitChanges();
}
现在第二次提交(被捕获的那个)再次抛出 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
}
}
编辑:找到了!
感谢已接受答案中的博客链接,我现在遍历所有冲突并记录它们以查看导致此问题的原因。
我很高兴我做到了,因为事实证明其中一个 DB 字段包含一个触发器,该触发器在某些条件下会更新其他内容。所以我可以随心所欲地解决,每次触发器都会再次触发,从而引发下一次冲突。
这个触发器显然我没有意识到,因为我的数据库管理员把它放在那里以跟踪某事或其他。触发器可能是一个很好的工具,但如果您不了解它们,它们可能会引起严重的头痛!
【问题讨论】:
标签: c# .net linq-to-sql concurrency