0

MainQという名前のキューから読み取る MessageBean があります。 onMessage コードの実行により、あるタイプのユーザーベースの例外がスローされた場合は、UserExceptionという名前を付けます。これをキャッチして、このメッセージをUserErrorQという名前の別のキューに配置します。例外がこのタイプでない場合、DMQ によって処理されるように例外がスローされます。

これが私の問題です:

  • 私の catch ブロックでは、ErrorQueueHandler を介して、この新しいメッセージを UserErrorQ に配置しようとします。これにより、connectionFactory に接続して UserErrorQ にメッセージを送信しようとするとエラーが発生します。
  • どうやら QueueConnectionFactory(javax.jms.ConnectionFactory) への新しい接続を作成すると問題が発生する

エラー:

com.sun.messaging.jms.JMSException: MQRA:DCF:allocation failure:createConnection:Error in allocating a connection. Cause: javax.transaction.RollbackException 
at com.sun.messaging.jms.ra.DirectConnectionFactory._allocateConnection(DirectConnectionFactory.java:548)
at com.sun.messaging.jms.ra.DirectConnectionFactory.createConnection(DirectConnectionFactory.java:265)
at com.sun.messaging.jms.ra.DirectConnectionFactory.createConnection(DirectConnectionFactory.java:244)`

メッセージ Bean:

@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void onMessage(Message message) {
   try{
    .
    .
   }catch(Exception e){
       if(isUserExceptionWrappedInException(e){
           errorQueueHandler.sendToErrorQueue(message);
       }
   }
}

private boolean isUserExceptionWrappedInException(Throwable t) {
    if (t == null)
        return false;
    else if (t instanceof UserException)
        return true;
    else
        return isUserExceptionWrappedInException(t.getCause());
}

エラーキューハンドラ:

public void sendToErrorQueue(Message message) {
    try {
        createConnection();
        send((TextMessage)message);
    } finally {
        closeConnection();
    }
}

private void createConnection() throws Exception {
    try {
        connection = connectionfactory.createConnection();
        connection.start();
    } catch (JMSException e) {
        String msg = "Error while attempting to initialize connection to jms destination " + ERROR_QUEUE;
        throw new OperationalException(msg, e, OperationalExceptionType.APPLIKASJONSTJENER);
    }
}

前述のように、接続しようとするとエラーが発生します。誰でもこれを修正できますか?

4

1 に答える 1

0

だから、私は自分の質問に対する答えを見つけました。connectionException の理由は、ErrorQueueHandler が EJB ではなく、CDI を介して注入されたためです。コンテナーが Bean インスタンスを破棄するため、ロールバック状態内で許可される新しいインスタンス化はありません。これが失敗の理由です。私の REQUIRES_NEW アノテーションも無視されました。これは javax API に属しているためです。これは CDI インジェクション Bean には影響しません。

以下にいくつかの注意事項を示します。

  1. EJB にコンストラクターがないか、パブリックコンストラクターがないことを確認してください。修飾子は重要です。コンテナが EJB をインスタンス化するためにこれらを正しくする必要があるからです。

  2. このアプローチにはいくつかの問題があります。

    • DMQ の代わりに別のエラー キューにメッセージを書き込もうとしているので、メッセージを消費し、後でエラーをスローしないようにする必要があります。MDB はロールバック状態にあるため、JMS 仕様では、これによりメッセージが再配信されることが明確に示されています。カスタム errorQueue に書き込んだ後、メッセージがすぐにキューに戻ってしまい、無限ループが発生します。

幸いなことに、解決策もあります。ここでの主な問題は、トランザクションを制御することです。このシナリオでは、3 つのトランザクションが必要です。

  1. RuntimeExceptionがあってもメッセージイベントを確認できるように、MDBの1つのトランザクション。
  2. onMessage メソッドのロジック用の 1 つのトランザクション。これにより、例外が発生したときにロールバックを実行できますが、それでも ErrorQueue に書き込むことができます。
  3. ロールバック状態で ErrorQueue に接続して書き込むための 1 つのトランザクション。

コード:

メッセージ Bean:

@EJB
QueueService queueService;

@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void onMessage(Message message) {
  try{
    queueService.processMessageInNewTrasaction(message);
  }catch(Exception e){
    throw e;
  }
}

キュー サービス:

import javax.jms.Message;
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
@Stateless
public class QueueService {

  @EJB
  ErrorQueueHandler errorQueueHandler;

  public void processMessageInNewTransaction(Message message){
    try {
    .
    .
    } catch(Exception e) {
      if(isUserExceptionWrappedInException(e)
        errorQueueHandler.sendToErrorQueue(message);
    }
  }

  private boolean isUserExceptionWrappedInException(Throwable t) {
    if (t == null)
      return false;
    else if (t instanceof UserException)
      return true;
    else
      return isUserExceptionWrappedInException(t.getCause());
  }

}

エラーキューハンドラ:

@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
@Stateless
public class ErrorQueueHandler{
   public void sendToErrorQueue(Message message){
   .
   .
   }
}

役立つリソース: http://weblogic-wonders.com/weblogic/2011/01/10/working-with-jms-and-the-standard-issues-in-jms/

于 2014-06-12T10:42:55.653 に答える