EF4を使用するいくつかのリポジトリ パターンプロジェクトに、次の疑似コードがあります。
public void Delete(int someId)
{
// 1. Load the entity for that Id. If there is none, then null.
// 2. If entity != null, then DeleteObject(..);
}
非常に単純ですが、実行時エラーが発生します:-
ConcurrencyException: Store、Update、Insert、または Delete ステートメントが予期しない数の行 (0) に影響を与えました。
今、これが起こっていることです:-
- EF4 の 2 つのインスタンスがアプリで同時に実行されています。
- インスタンス A が delete を呼び出します。
- インスタンス B は、1 ナノ秒後に削除を呼び出します。
- インスタンス A がエンティティをロードします。
- インスタンス B もエンティティをロードします。
- インスタンス A はそのエンティティを削除します - クールなバナナ。
- インスタンス B はエンティティを削除しようとしますが、エンティティは既に削除されています。そのため、ノーカウントまたはそうでないものは0であり、1..またはそのようなものを期待していました。基本的に、削除するはずのアイテムが削除されていないことがわかりました (ほんの数秒前に発生したため)。
これが競合状態か何かのようなものかどうかはわかりません。
とにかく、2番目の呼び出しがクラッシュしないように、ここでできるトリックはありますか? 私はそれをストアドプロシージャにすることができました..しかし、今はそれを避けたいと思っています。
何か案は?選択が呼び出されたときにその行(およびその行のみ)をロックできるかどうか疑問に思っています...行ロックが解除されるまでインスタンスBを強制的に待機させます。その時までに、行は削除されるため、インスタンス B が選択を行うと、データは存在しません..削除されることはありません。