メッセージがキューから読み取られるとき (破壊的な呼び出し)、後で TX がロールバックされた場合 (MDB コンテナーで管理された TX)、メッセージがキューに戻されることを観察しました (バックカウントとキューのしきい値設定に応じて、元のキューまたはバックアウト キュー)。 . TX のロールバックが失敗したために何かが発生した場合 (繰り返されるネットワークの問題または何らかの問題)、メッセージが失われるとしましょう。
本当ですか??
ありがとう
前の質問へのコメントで述べたように、短い答えは「いいえ、失敗しても WMQ はそれらのメッセージを失うことはありませCOMMIT
ん」ですが、もう少し詳しく見てみましょう。
クライアントがネットワーク経由で MQ に接続すると、MQ は、MQ への共有メモリ接続とクライアント アプリケーションへのソケット接続を作成するプロセスを開始します。トランザクションを開いたままにしておくのは、WMQ 用語で「チャネル エージェント」と呼ばれる共有メモリ プロセスです。
COMMIT
アプリケーションの観点から失敗したように見える2 つのケースがあります。これらの最初の例でCOMMIT
は、 がチャネル エージェントに配信されて実行されますが、ネットワークの問題により、確認がアプリケーションに返されることはありません。GET
MQ の観点からは、アプリが意図的に呼び出しをコミットしたため、メッセージが「失われた」わけではありません。
COMMIT
2 番目のケースは、 がチャネル エージェントに到達する前にネットワーク障害が発生した場合です。この場合、COMMIT
アプリはトランザクションが存在する接続ハンドルを回復できないため、本当に失敗しています。チャネル エージェントは、TCP 接続が失敗したことを認識すると、トランザクションをバックアウトしてチャネルを閉じます。このプロセスの問題点は、チャネル エージェントが接続が切断されたことを認識するまでに時間がかかることです。実際、ほとんどのプラットフォームでのデフォルトの TCP タイムアウトは 2 時間です。サーバーの TCP 設定に応じて、トランザクションGET
そのメッセージを同期点で最大 2 時間保持し、消費されたように見せることができます。これが、現在のレベルの QMgr とクライアントを使用することが強く推奨される理由の 1 つです。失われた接続を検出するために、TCP への依存度が低くなり、内部チャネル ハートビート プロトコルへの依存度が高くなります。
アプリケーションの観点からは、これらのケースはどちらも同じように見えます - app 呼び出しCOMMIT
と 2009 を取得しますMQRC_CONNECTION_BROKEN
。ただし、最初のケースではメッセージが原因で失わCOMMIT
れ、2 番目のケースではメッセージが再度配信される可能性があります。このあいまいさのため、アプリは重複メッセージを検出して適切に処理できる必要があります。
これが MQ の欠陥であると断言する前に、この結果のあいまいさは、ネットワーク経由でメッセージングを使用する場合に固有のものであり、WebSphere MQ に固有のものではないことを指摘しておきます。実際、JMS 1.1 仕様では、4.4.13 でこれに直接対処しています。
クライアントがセッションで作業をコミットしてから commit メソッドが戻るまでの間に障害が発生した場合、クライアントはトランザクションがコミットされたかロールバックされたかを判断できません。PERSISTENT メッセージの非トランザクション送信と送信メソッドからの戻りとの間に障害が発生した場合にも、同じあいまいさが存在します。
このあいまいさに対処するのは、JMS アプリケーション次第です。場合によっては、これによりクライアントが機能的に重複したメッセージを生成することがあります。
セッション回復のために再配信されたメッセージは、重複メッセージとは見なされません。
したがって、同期点を使用すると、メッセージが失われるケースを排除できます。これは、キューからメッセージを永続的に削除するには、メッセージのGET
後に a が続く必要があるためです。COMMIT
定義上、COMMIT
アプリケーションがメッセージを確認するまで は到着できません。ただし、同期点はメッセージの重複の可能性を排除できません。これは、いずれかのCOMMIT
がGET
失敗した場合、アプリがメッセージを再度表示する可能性があるためです。同様に、の が失敗しCOMMIT
たPUT
場合、アプリは がCOMMIT
チャネル エージェントに到達する前に失敗したのか、到達した後に失敗したのかを知る方法がなく、再接続しPUT
てメッセージを再度送信するしかありません。
実際に「失われた」メッセージが発生している場合は、次の可能性があります。
COMMIT
が、メッセージの別のコピーを送信しませんでした。GET
ting アプリが失敗しCOMMIT
、メッセージは失われていませんが、実際には同期点にあります。その場合、孤立したチャネルを停止して、トランザクションをロールバックします。これらの 2 つのケース以外では、WMQ はその永続的なメッセージを失うことはありません。
いいえ。メッセージは失われません。トランザクションでは、メッセージはコミットが成功した後にのみキューから削除されます。コミットまたはロールバックが失敗すると、メッセージが再表示されます。コミットまたはロールバックが呼び出される前にアプリケーションとキュー・マネージャー間の接続が切断された場合、WebSphere MQ は自動的にロールバックを行います。これにより、メッセージが失われないことが保証されます。