9

私はActiveMQメッセージを送信するために使用しています。

ですから、私がメッセージを送ったとき、そのメッセージはメッセージを受け取るようになります。挿入が成功すると、確認されます。

しかし、確認後にコードがあり、スローする可能性がありますNullPointerException

したがって、その例外を意図的に生成するために、をスローしNullPointerExceptionました。だからそれがそれをするとき:

メッセージはそうではなくdequeued、同じメッセージが再びonMessage関数に届きます。

私のコードは次のとおりです。

public void onMessage(Message message) {
    String msg = null;
    try
    {
        msg = receiveMessage(message);

        // Other code to insert message in db

        message.acknowledge();

        if(true)
        {
            throw new NullPointerException("npe"));
        }
            ** // Other code which might produce a null pointer exception **
        }
        catch(Exception ex)
        {
        }
    }

私も持っているのに、なぜメッセージが再びonMessage()機能するようになるのですかacknowledge()

私はすでにdbにメッセージを挿入しているので。

キュー内のメッセージは削除されacknowledge()ませんか?

どうすればこれを達成できますか?

4

4 に答える 4

4

メッセージリスタナで自動確認モードを使用すると、仕様により、メッセージリスナーが正常に戻らなかった場合(たとえば、例外がスローされた場合)にメッセージが再配信されます。

あなたの場合、メッセージを手動で確認しようとしていますが、で作成されたセッションを使用してそれを行うことはできませんcreateSession(false, Session.AUTO_ACKNOWLEDGE)

あなたのコードはで動作したでしょうSession.CLIENT_ACKNOWLEDGE

それ以外の場合は、AUTO_ACKNOWLEDGEを使用しながら、onMessageメソッド内の例外をキャッチする必要があります。

メッセージをよりきめ細かく制御するには、トランザクションセッションの使用を検討し、を使用session.commit();してメッセージが読み取られたことを確認してください。

于 2012-09-14T20:50:40.847 に答える
3

トランザクション セッションを使用していないことを確認しましたか? トランザクション セッションを使用する場合、確認モードは無視されるため、次のようになります。

  • あなたmessage.acknowledge()は事実上ノーオペレーションです

  • メッセージリスナーをエスケープするときに、キャッチされなかった例外が「セッションロールバック」をトリガーし、メッセージの再配信を強制します。

注:公開されたコードには があるcatch (Exception ex) { }ため、例外がどのように外部にエスケープされるか正確にはわかりません。

于 2012-09-18T21:29:20.093 に答える
2

メッセージを処理するための別のメソッドを作成できます。つまり、onMessage()関数で、そのメッセージをデータベースに挿入するためだけのコードを記述します。

そして、そのメッセージを処理するための別の関数を作成します。

処理中にエラーが発生した場合、メッセージがonMessage()再度表示されないようにします。

于 2012-09-24T15:08:52.053 に答える
0

トランザクションJMS確認応答モードを使用する場合、メッセージは、例外なく処理されるか、JMSコンテナによってDQLキューに移動されるまで、JMSリスナーによって数回受信されます(AMQではデフォルトで約8回です)。詳細については、メッセージの再配信とDLQ処理を参照してください。

トランザクションの管理は、使用するフレームワークによって異なります。私はSpringFrameworkを使用することを好むので、SpringXML構成は次のようになります。

<jms:listener-container container-type="default"
                        connection-factory="calendarConnectionFactory"
                        acknowledge="transacted"
                        destination-type="queue"
                        cache="consumer"
                        concurrency="1-5">
    <jms:listener destination="${jms.calendar.destination}" ref="calendarListener"/>
</jms:listener-container>

そして私のメッセージリスナーのJavaコードは

@Override
@Transactional(propagation = Propagation.REQUIRED,
               noRollbackFor =
                 {ClassCastException.class, IllegalArgumentException.class})
public void onMessage(Message message) {
 ....
}

したがって、どの例外がトランザクションをロールバックするかどうかを管理できます。

于 2012-09-14T15:51:55.173 に答える