1

オプティミスティック コンカレンシー例外について疑問があります。

たとえば、データベースからいくつかのデータを取得し、いくつかのレジスタを変更してから、変更を送信します。私の要求と私の更新の間に誰かがレジスタの情報を更新すると、楽観的な例外が発生します。古典的な並行性の問題。

私の最初の疑問は次のとおりです。EF は、情報が変更されているかどうかを判断し、データベースからデータを取得し、取得した元のデータとデータベースから取得したデータを比較します。違いがある場合は、オプティミスティック同時実行例外がスローされます。

オプティミスティック同時実行例外をキャッチした場合、クライアントが勝つかストアが勝つかを決定します。このステップで、EF は情報を再度取得するか、最初に取得したデータを使用しますか? 再度データを取得すると効率が悪いからです。

2 番目の疑問は、オプティミスティック同時実行例外を制御する方法です。コードの catch ブロックで、クライアントが勝つかストアが勝つかを決定します。クライアントが勝ったら、saveChanges を再度呼び出します。しかし、クライアントが勝ったと判断してから変更を保存するまでの間に、他のユーザーがデータを変更する可能性があるため、楽観的同時実行例外が再び発生します。理論的には、無限ループになる可能性があります。

クライアントがデータベース内の情報を確実に更新できるように、トランザクション (スコープ) を使用するのは良い考えでしょうか? 他の解決策は、ループを使用してデータを更新するために N 回試行することです。それが不可能な場合は、終了してユーザーに伝えます。

取引は良い考えでしょうか?データベースのリソースを大量に消費しますか? トランザクションはデータベースを一瞬ブロックしますが、更新操作が確実に終了するようにします。操作を完了しようとする N 回のループ、データベースを N 回呼び出すため、さらに多くのリソースが必要になる可能性があります。

ありがとう。ダイムロック。

編集:私は尋ねるのを忘れました。同時実行例外を待機する代わりに、デフォルトでクライアント wins を使用するようにコンテキストを設定することは可能ですか?

4

1 に答える 1

5

私の最初の疑問は次のとおりです。情報が変更されているかどうかを判断するEFは、データベースからデータを取得します...

データベースから追​​加のデータを取得することはありません。同時実行処理に使用されるエンティティの元の値を取得し、更新コマンドの where 条件で使用します。更新コマンドの後に、変更された行数を選択します。数字が 0 の場合、レコードが存在しないか、誰かが変更したことを意味します。

2 番目の疑問は、オプティミスティック同時実行例外を制御する方法です。

Refreshとを呼び出すだけですSaveChanges。必要に応じて、パターンを数回繰り返すことができます。非常に多くの同時実行アプリケーションがあり、複数のスレッドが数秒以内に同じレコードを更新しようと戦っている場合は、おそらくデータ ストレージを別の方法で設計する必要があります。

クライアントがデータベース内の情報を確実に更新するために、トランザクション (スコープ) を使用することは良い考えでしょうか?

SaveChanges常にデータベース トランザクションを使用します。SaveChangesTransactionScope は、複数の呼び出しでトランザクションを使用したり、分散トランザクションを使用したり、トランザクションの分離レベルなどを変更したりしない限り、追加の価値を追加しません。

同時実行例外を待機する代わりに、デフォルトでクライアント wins を使用するようにコンテキストを設定することは可能ですか?

デフォルトで設定されています。どのプロパティにもマークを付けないだけで、ConcurrencyMode.Fixed同時実行処理がなくなります = クライアントが勝ちます。

于 2012-05-28T09:44:27.333 に答える