JMS メッセージを宛先に確実に送信できますか? 確実にということは、たとえばMessageProducer.send()
呼び出しが何らかの理由で失敗した場合に、自動的に再試行されることを保証することを意味します。トランザクション セッションが.recover()
最後の手段として使用される可能性があることは認識していますが、再試行についてはどうでしょうか。たとえば、セッションが確立されてメッセージを送信しようとする間に断続的なネットワーク障害が発生しました。この場合、どのようにrecover()
役立ちますか?
2 に答える
私の知る限り、JMS はそのような動作をサポートしていません。特定のベンダー拡張を検索することはできますが、私見では、ニーズに適したものが見つかる可能性は低いです。
あなたの問題に対する解決策は2つしかありません。
実装します。JMS セッションを手動で管理し、例外をキャッチし、必要に応じてトランザクション マネージャーの「ロールバックのみを設定」機能を使用してトランザクションを無効にすることができます。
ローカル キューを使用してメッセージを保存し、バックグラウンド サービスを使用してメッセージをターゲット リモート キューに移動します。ActiveMQ の Store and forward Queues など、多くのキュー マネージャーがこれをサポートしていることに注意してください。明らかに、この方法では、トランザクション境界にはリモート キューが含まれません。
2番目の解決策があなたの問題に対する完全な解決策ではないことは知っていますが、多くの場合、それで十分です.
JMS は、探している動作を指定しません。実際、JMS は、同じメッセージを 2 回受信する可能性があることに注意することで、ネットワーク障害による問題に具体的に対処します。JMS ブローカーの観点からは、メッセージは 1 回しか配信されていないため、これを「機能的に重複した」メッセージと呼びます。
これは JMS の一部ではないため、答えはさまざまなベンダーの実装にあります。たとえば、WebSphere MQ には、v7.0.1 の時点で「Multi-Instance Queue Manager」と呼ばれる機能があります。v7.0.1 クライアント アプリケーションは自動的に接続を再試行し、障害が発生した場合はプライマリ ノードからセカンダリ ノードまで QMgr に従います。これが発生している間、アプリケーションはブロックされ、フェイルオーバーを認識しません。
ただし、この動作を行っても、アプリはエラーに対するコーディングを行う必要があります。たとえば、WMQ の自動再接続 (または任意のプロバイダーの再接続) を使用する場合、ユーザーが無期限にハングしないように、アプリが接続の回復を待機するまでの時間を調整する必要があります。呼び出しのブロックが解除されると、トランザクションはロールバックされ、コードで再試行する必要があります。トランザクションは無効になった接続に関連付けられているため、これは適切です。