3

以下のようなEJBがあります-

class ActivityProcessor{
     @Resource
     private SessionContext context;

     @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
     public boolean processActivity(Activity activity) throws Exception{
          try{
             //required code for processing activity
          }catch(Exception ex){
            //Exception while processing activity
            handleException(ex,activity); 
            context.setRollbackOnly();
            throw ex;   
          }  
     } 

     @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
     public void handleException(Exception ex, Activity activity)  {
          //Code to save this activity in exception table 
     }
}

処理が失敗した場合にアクティビティを例外 DB テーブルに保存するという要件があります。しかし、上記のコードでは、processActivityに例外がある場合、 handleExceptionメソッドでトランザクション タイムアウト例外が発生します。handleExceptionは個別に正常に動作しています。

EJB トランザクションのこの問題について教えてください。

私の理解では、1. processActivity に対して新しいトランザクションが作成されます。

  1. processActivityで例外が発生した場合、handleExceptionが呼び出されます。トランザクション属性がREQUIRES_NEWであるため、processActivityのトランザクションは中断され、handleExceptionに対して新しいトランザクションが作成されます。

  2. handleException が成功した場合、handleException のトランザクションは保存されます。

  3. processActivity の中断されたトランザクションは再開されますが、context.setRollbackOnly により、ロールバックされます。

4

2 に答える 2

2
  • handleExceptionから内部的に呼び出していますprocessActivity。おそらく、コンテナは同じトランザクションでそれを実行し、新しいトランザクションを生成しません。
  • JNDI ルックアップまたはインジェクションを介して参照を取得してから、それを呼び出しhandleExceptionたり、他の Bean に移動したりしてください。
于 2013-05-27T08:03:53.830 に答える
0

ここでの問題は、handleExceptionメソッドを直接呼び出していることです。このようにして、アプリケーション サーバーはトランザクション処理コードを挿入する機会がありません。

EJBObject次のように、によって公開されたを介して同じメソッドを呼び出してみてくださいSessionContext

class ActivityProcessor{
 @Resource
 private SessionContext context;

 @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
 public boolean processActivity(Activity activity) throws Exception{
      try{
         //required code for processing activity
      }catch(Exception ex){
        //Exception while processing activity
        context.getBusinessObject(ActivityProcessor.class)
          .handleException(ex,activity); 
        context.setRollbackOnly();
        throw ex;   
      }  
 } 

 @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
 public void handleException(Exception ex, Activity activity)  {
      //Code to save this activity in exception table 
 }
}
于 2013-05-28T20:48:50.203 に答える