0

再試行インターセプターを使用して、基本的な楽観的ロックメカニズムを実装しようとしています。

つまり、responsesCountプロパティを持つオブジェクトクイズがあります。クイズの更新中に楽観的なロック例外がスローされた場合、それぞれの更新メソッドが再試行インターセプターから再度呼び出されます。

再試行されたメソッドは毎回同じバージョン番号番号を持っているため、何かが正しくないということです。このため、何があってもトランザクションは失敗します。

バージョン:10

プロセスA:更新クイズの開始、バージョン10プロセスB:更新クイズの開始、バージョン10プロセスB:更新クイズの終了、バージョン11プロセスA:楽観的な例外がスローされ、更新クイズが発生し、プロセスAを再試行します。再試行されたメソッド内のバージョンは常に10です。

それでは私は何ができますか?トランザクションを成功させるには、バージョンを自動的にインクリメントする必要があります

4

3 に答える 3

1

他の誰かがあなたの後ろでクイズを更新したとしても、あなたはクイズを更新したいと思うようです(これは楽観的な例外をスローします)。その場合、なぜこのエンティティで楽観的なロギングを有効にするのですか?バージョンフィールドを削除するだけで、再試行しなくても機能します。

本当にバージョンフィールドを保持したい場合は、DBからクイズを取得するようにメソッドを変更し、新しくロードされたクイズのバージョン番号をデタッチされたインスタンスにコピーしてから、デタッチされたインスタンスをマージしてすべての新しい値をにコピーします。付属のもの。

于 2011-03-01T11:24:42.163 に答える
1

楽観的なロック例外は次のように処理されます。

最初にレコードを再読み取りし、競合するトランザクションが書き込んだ新しいバージョン番号と更新されたフィールド値を取得します。

次に、新しい値に基づいて操作を再適用します。あなたの場合、これは単純です-値の増分は順序に依存しないか、可換です。他の操作は、再適用するのが簡単ではない場合があります。たとえば、トランザクションが両方とも、課題追跡システムのバグをあるワークフロー状態から別のワークフロー状態に移動しようとしたとします。この移行は1回しか発生しないため、再試行するトランザクションでは、バグがその移行に対してまだ有効な状態にあることを確認する必要があり、そうでない場合は、ユーザーにエラーが報告されます。

于 2011-03-01T21:42:44.877 に答える
0

あなたは楽観的なロックを打ち負かそうとしています:D、それは問題を提起します:あなたは楽観的なロックが必要ですか?

以前のデータを失うことなく再試行する唯一の正しい方法は、オブジェクトを更新してから変更を再度適用することです...いずれにしても、データをオーバーライドすることになり、楽観的なロックの考え方に反します。

あなたの場合、楽観的ロックをまったく無効にするか、楽観的ロックなしでカウントを補助テーブルに入れます。

于 2011-03-01T11:24:32.357 に答える