好的,所以你认为你是一个真正的调试器?试试这个:
我有一个 Linq2Sql 项目,突然我们发现偶尔,看似随机,我们会得到同一行的双插入。
我已经继承DataContext和覆盖了SubmitChanges. 在里面,我在调用GetChangeSet()之前和之后都调用了base.SubmitChanges(),并使用文本文件记录器来记录Inserts集合中的对象。另外,我保留对插入对象的引用足够长的时间来记录它们的自动编号 ID。
当双插入发生时,我在数据库中看到,不是每行都插入到MyTableAandMyTableB中,而是每行有两行。SQL Profiler 显示四个插入语句,一个接一个地快速连续:
insert into MyTableA(...
insert into MyTableB(...
insert into MyTableA(...
insert into MyTableB(...
我检查了调试日志,集合中只有两个对象Inserts:一个和一个。在调用 之后,变更集是空的(应该是)。并且自动编号 ID 显示新插入行的较大值。MyClassAMyClassBbase.SubmitChanges()
另一条有用的信息:在调试模式下单步执行时永远不会发生错误;仅当您在没有断点的情况下运行时。这让我怀疑这与执行速度有关。
我们已经使用同一DataContext个子类一年多了,而且我们以前从未在我们的产品中看到过这种行为。它只发生在MyClassAandMyClassB上。
总结一下:
- 从调试日志来看,一切看起来都正常。
- 在 SQL Profiler 上,您可以看到正在发生双插入。
- 这种行为经常发生,但出乎意料,只发生在提到的两个类中,除了在调试模式下单步执行代码时它从不发生。
编辑 - 新信息:
在我的DataContext子类中,我有以下代码:
try {
base.SubmitChanges(ConflictMode.ContinueOnConflict);
} catch (ChangeConflictException) {
// Automerge database values for members that client has not modified.
foreach (ObjectChangeConflict occ in ChangeConflicts) {
occ.Resolve(RefreshMode.KeepChanges);
}
}
// Submit succeeds on second try.
base.SubmitChanges(ConflictMode.FailOnFirstConflict);
MyTableA并且MyTableB两者都有一个强制性的外键OtherTableID引用OtherTable。双重插入发生在ChangeConflictException公共父表更新期间发生的情况下OtherTable。
我们闻到气味了,现在...