0

OptimisticLockException が EJB レイヤーによって発生したときに、Web レイヤー (.war コード) で OptimisticLockException をキャッチする方法という 1 つの問題があります。

JEE5、GlassFishV2.1、JPA (TopLinks を使用)、およびコンテナ管理のトランザクションを使用しています。しかし、同じエンティティに対する別の同時ユーザーによるトランザクションが原因でダーティ リードが発生すると、実際に発生した war レイヤーで Transaction.RollBackException が発生します。 OptimisticLockException によって。しかし、戦争側で OptimisticLockException をキャッチできません。

インターネットで見つけました
http://books.google.com/books?id=fVCuB_Xq3pAC&pg=PA292&dq=OptimisticLockException++Collision+Exception&hl=en&ei=0A6jTI3nN5DQccbO5MAB&sa=X&oi=book_result&ct=result&resnum=1&ved=0CCgQ6AEwAA#v=onepage&q=OptimisticLockException%20 %20Collision%20Exception&f=false

em.flush を ejb 側で使用すると、いくつかのカスタム例外をキャッチして war にスローできます。しかし、 em.flush はすべてのデータベースを更新すると思いますが、それは高価な操作ですか?

try{
   //some enitity
   em.flush()
  }
catch(OptimisticLockException ole){

throw ole;
}

私の意見では、90% のケースで OptimisticLockException が発生しないため、em.flush を呼び出さず、.war で EJBException をキャッチしてから再試行します。より良いオプションはありますか?

try{ // コード } catch (EJBException ex) {

      if (ex.getCausedByException().getCause().toString().
          indexOf("javax.transaction.RollbackException")!= -1){
               // do work
          }     
      }
   }
4

1 に答える 1

1

どちらでも構いません。flush() は技術的に高価な操作ではありません。データベースへの書き込みで行う作業はコミットによって行う必要がなくなったため、余分なデータベース アクセスがなく、「すべてのデータベースを更新」しません。ただし、flush() には多少のオーバーヘッドがあります。変更は、コミットで 1 回に対して、フラッシュで 1 回、コミットで 1 回の 2 回計算されます。変更ポリシーと管理対象オブジェクトの数によっては、コストがかかります。フラッシュでは、管理対象オブジェクトを追跡管理状態に戻す必要もあります。これにもコストがかかりますが、データベース アクセス コストに比べれば一般的にはわずかです。

コミット中にロック エラー以外のエラーが発生する可能性があることに注意してください。そのため、フラッシュを使用してロック エラーをキャッチしたとしても、他の失敗の原因を処理するために war にコードが必要になるため、フラッシュを使用せず、一般的なトランザクション失敗エラー処理が最善の解決策かもしれません。ロックエラーに対して何か特別なことをしたい場合は、チェーンによって原因で例外を見つけることができるはずですが、操作を再試行するだけに注意してください。理由でロックしているので、おそらくエラーを報告する必要がありますユーザーに操作を再試行してもらいます。

于 2010-09-29T13:57:51.687 に答える