4

シナリオを考えてみましょう: バージョン管理された異なるテーブルから複数の行を含む Db トランザクション。

例: shopLists と製品。shopList に商品 (ショップリストにある商品の量) が含まれていて、商品に現在の在庫がある場合。

shopList を挿入または編集するときに、shopList 内のこれらの製品の在庫を更新して、在庫を一定に保つ必要があります。

そのために、トランザクションを開き、shopList を挿入/更新し、各製品の在庫を更新 (デルタを適用) してから、トランザクションをコミットします。今のところ大したことはありません。

ただし、他のユーザーが共通して 1 つまたは複数の製品を更新した可能性があります。または、shopList 自体を更新することもできます。どちらの場合も、トランザクションをコミットするときに StaleObjectStateException が発生します。

質問: StaleObjectStateException の原因となったテーブルを特定する方法はありますか?

製品が例外を引き起こした場合、関連するすべての製品を DB から更新してから、在庫デルタを再適用できます。そして、それは結構です。shopList が例外を引き起こした場合は、ユーザーが最初からやり直すことができるように、単に問題をユーザーに報告することをお勧めします。

どうもありがとうございました。

4

1 に答える 1

4

方法がわかりました。

まず最初に、JPA (または hibernate 自体) が org.hibernate.StaleObjectStateException 例外を javax.persistence.OptimisticLockException としてラップします。したがって、適切な例外をキャッチしたい場合は、OptimisticLockException を使用してください。

2 番目: コミット前に EntityManager のメソッド Flush を呼び出すと、休止状態は OptimisticLockException のみをスローします。Commit を直接呼び出すと、代わりに別の例外が発生します (どの例外かは忘れました)。ほとんどすべての人が commit メソッドによって発行された例外をキャッチしてトランザクションのロールバックを行うことを考えると、ロールバックに関連する例外が発生します (どれがもう一度思い出せません)。

3 番目と最後に、元の質問に答えます。バージョン管理エラーの原因を取得するには、OptimisticLockException インスタンスから getEntity メソッドを呼び出すだけです。それに関連して必要なものはすべて提供されます。

ここを通りかかったすべての人に感謝します。それに関するご質問は、お気軽にお尋ねください。喜んでお手伝いさせていただきます。

于 2011-01-30T00:27:24.267 に答える