Tapestry5(java webframework)とHibernateで作成されたWebアプリケーションがあります。今、私は楽観的ロックを追加しようとしています。そこで、バージョン属性を追加し、楽観的ロックが機能するようにしたので、それは簡単で高速でした。
しかし、私のWebアプリケーションは「要求ごとのセッション」パターンで動作するため、この楽観的ロックを利用するための最良の方法がわかりません。
何が起こるのですか:
UserAは、entityA(バージョン1)からの値がロードされたフォームでページを開きます。
UserBは、entityA(バージョン1)からの値がロードされたフォームでページを開きます。
UserAはいくつかの値を変更し、フォームを送信します。->新しいリクエストはentityA(バージョン1)を取得し、変更をコミットします(entityAはバージョン2になりました)
UserBはいくつかの値を変更し、フォームを送信します。->新しいリクエストはentityA(バージョン2)を取得し、変更をコミットします(entityAはバージョン3になりました)
何が起こるべきか
UserBの変更はコミットしないでください。ただし、リクエストごとのセッションパターンのため、Hibernateの楽観的ロックエラーが発生する可能性のある時間枠は、送信からコミットまでの新しいリクエストからの期間に短縮されます。これは望ましい結果ではありません。
可能な解決策
いくつかの調査の後、私は次のことを発見しました:
- エンティティバージョンを使用してフォームに非表示フィールドを追加します
この値を使用して、コミット前にエンティティのバージョンを設定できますが、Hibernateのドキュメントではこの値の設定を推奨していません。また、エンティティがデタッチされて再接続された場合にのみ機能します。それ以外の場合、手動で設定されたバージョン値はHibernateによって無視されるためです。
次に、このバージョン値を使用して、フォームがレンダリングされたときのバージョンが、送信時にリクエストにロードされたエンティティのバージョンと同じであるかどうかを手動で確認できます。次に、必要に応じて自分でOptimisticLockingExceptionをスローします。
- デタッチされたエンティティをHttpSessionに配置するので、送信時に再度ロードする必要はありません。
結論
これらの方法は機能しますが、私にはあまり実用的ではなく、間違いを犯しやすいようです。だから私は他の人がこの問題をどのように実装しているのだろうかと思っています。