では、あなたは本物のデバッガーだと思いますか? これを試してください:
私は Linq2Sql プロジェクトを持っていますが、突然、時折、一見ランダムに、同じ行の二重挿入が発生することを発見しました。
をサブクラス化DataContextし、オーバーライドしSubmitChangesました。その中で、GetChangeSet()の呼び出しの前後に を呼び出しbase.SubmitChanges()、テキスト ファイル ロガーを使用してInsertsコレクション内のオブジェクトを記録しました。さらに、自動番号付けされた ID を記録するのに十分な時間、挿入されたオブジェクトへの参照を保持します。
MyTableA二重挿入が発生すると、DB で、それぞれ 1 つの行がandに挿入される代わりに、それぞれMyTableB2 つの行があることがわかります。SQL プロファイラーは、4 つの挿入ステートメントを 1 つずつすばやく連続して表示します。
insert into MyTableA(...
insert into MyTableB(...
insert into MyTableA(...
insert into MyTableB(...
Insertsデバッグ ログを確認すると、コレクションには のとのの2つのオブジェクトしかありません。への呼び出し後、変更セットは空です (そうあるべきです)。また、自動付番 IDは、新しく挿入された行の大きい方の値を示します。MyClassAMyClassBbase.SubmitChanges()
もう 1 つの有用な情報:デバッグ モードでステップ実行する場合、バグは発生しません。ブレークポイントなしで実行した場合のみ。これは、実行速度に関係していると思われます。
同じDataContextサブクラスを 1 年以上使用していますが、この種の動作は製品で見たことがありません。と でのみ発生しMyClassAますMyClassB。
要約する:
- デバッグ ログから、すべてが正しく機能しているように見えます。
- SQL プロファイラーでは、二重挿入が発生していることがわかります。
- この動作は、デバッグ モードでコードをステップ実行するときに発生しないことを除いて、前述の 2 つのクラスに対してのみ、頻繁に発生しますが、予測できません。
編集 - 新しい情報:サブクラス
内に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。
私たちは今、香りに取り組んでいます...