1

私はオブジェクトGeneralKnowledgeTestを持っており、ユーザーがそのテストを受けるたびに更新される多くの統計フィールド(ratingsCount、responsesCount、ratingStars ...)が含まれています(takeTest()->トランザクションメソッド)。

多くのユーザーが同時に同じテストを受けている可能性があるため、楽観的ロック(@version)と、楽観的ロック例外がスローされた場合にtakeTestメソッドを再試行するインターセプターを実装することを考えていました。

したがって、takeTestメソッド内では、常に新しいGeneralKnowledgeTestインスタンス(entityManager.find(testId)など)を取得してから、その統計フィールドを更新します。楽観的な例外がスローされた場合、インターセプターは成功するまでtakeTestメソッドを再試行します。

この手順についてどう思いますか。これは、多くのユーザーが同じテストを受けようとしている可能性のあるシステムに楽観的ロックを実装するための良い方法ですか?

PS。楽観的なロック例外がスローされた場合、企業は警告メッセージを表示することを認めないため、スムーズな実行を可能にするためにインターセプターは必須です...

4

2 に答える 2

0

これらの統計はテストの最後にのみ更新され、テストの実行には妥当な時間がかかると思います。これにより、楽観的なロックが失敗する可能性が低くなります。また、設定した時間にテストを開始した結果、ユーザーが一気にテストを完了する可能性はありますか?これにより、ロックが失敗する可能性が高くなります。

同時更新の可能性が高いスループットの場合は、統計をメモリに集約し(スレッドセーフな方法で)、定期的にデータベースに書き込む方がよいでしょう。

于 2011-03-01T20:27:38.467 に答える
0

これは有効なアプローチのように聞こえます:

Hibernateはフラッシュ時にインスタンスのバージョンをチェックし、同時変更が検出された場合は例外をスローします。この例外をキャッチして処理するのは開発者の責任です。一般的なオプションは、ユーザーが変更をマージしたり、古くないデータでビジネス会話を再開したりする機会です。

IsolationLevelをSERIALIZEDに設定したり、テーブルの行をロックしたりすることもできます。

別のオプションは、オブジェクトをデタッチし、入ってくる統計でオブジェクトを更新し、スケジューラーなどを使用してオブジェクトを再アタッチ(更新)することです。ただし、これにはサービスメソッド(更新統計)の同期が必要な場合があり、このサービスはおそらくプロキシされているため、同期は不可能だと思います。

于 2011-03-01T20:35:33.950 に答える