4

この質問は、私が最もよく知っている Websphere MQ (WMQ) を使用する場合の Websphere Application Server (WAS) に主に焦点を当てています。ただし、私が話していることはすべて、より一般的にすべての Java EE アプリケーション サーバーに当てはまると思います。なぜなら、私は Java 標準インターフェースに固執しているためです。標準に関連する説明を希望しますが、WAS/WMQ に固有の回答には非常に興奮しています。

JMS 1.1 は、JMS がアプリケーション サーバーとインターフェースをとるためのメカニズムを定義します。大まかなプロセスは、キューまたはトピックを監視するために、ある時点で ConnectionConsumer が作成されることです。メッセージが表示されると、JMS 実装は ServerSessionPool から ServerSession オブジェクトを取得し、そのメッセージを ServerSession に関連付けられた Session にロードしてから、ServerSession オブジェクトで start() を呼び出します。次に、ServerSession は、アプリケーション サーバー スレッドで MDB によって処理されるようにメッセージをスケジュールする役割を果たします。MDB は onMessage() メソッドの一部としてメッセージを取得し、必要な処理を実行できます。

MDB が、受信したメッセージに応答して別のメッセージを送信することを決定するまでは、これで問題ありません。これを行うために、MDB は ConnectionFactory オブジェクトをルックアップまたは挿入し、Connection、Session、MessageProducer の順に取得し、最後にメッセージを送信する必要があります。これはすべて非常に無駄に思えます。MDB へのメッセージ配信の一部として、Connection オブジェクトと Session オブジェクトがすでに作成されています。MDB が何らかの方法でそのセッションにアクセスできる場合、余分な作業をすべて行う必要がなくなり、余分な接続をすべて作成する必要がなくなります。その余分な作業がコストとして発生します。要求メッセージに応答メッセージを送信するだけで、MDB は 2 つの接続と 2 つのセッション (メッセージを取得して応答を送信するために 1 つずつ) を使用する必要があります。グローバルトランザクションを使用する場合、これにより、アプリケーション サーバーはトランザクションを 2 フェーズ コミット トランザクションとして処理することになると思います (すべてではないにしても、少なくとも一部のアプリケーション サーバーは、1 フェーズ コミットとして処理することにより、単一のリソースのみを含むグローバル トランザクションを最適化できます)。 . トランザクションを 2 フェーズ トランザクションにすると、メッセージ処理のオーバーヘッドが大幅に増加し、あらゆる種類の新しい複雑さも導入されます (インダウト トランザクションは最大のトランザクションの 1 つです)。

JMS 1.1 仕様には次のように記されています。 MDB は、最初のメッセージを配信したセッションを使用して応答も送信します。ただし、この Session オブジェクトを MDB から標準的な方法で取得するメカニズムについては知りません。また、非標準的な方法でそれを取得するメカニズムも知りません。これに関する質問やブログ投稿がどこにも見つかりません。

では、問題は次のとおりです。JMS API は非常に複雑ですが、MDB が元のメッセージを供給したセッションを使用して、アクセスできる場合に応答を送信することを困難にするようなものは見当たりません。MDB がこの Session オブジェクトを使用できない理由はありますか? セッションにアクセスするための標準準拠の方法はありますか? 非標準に準拠した方法はありますか? アプリケーション サーバー/JMS 実装は、単一の JMS キュー マネージャー上の 2 つの接続での操作を含むグローバル トランザクションを 1 フェーズ コミット トランザクションに最適化するのが賢明ですか (標準に関する私の調査と理解では、これは不可能であることが示されているようです)。

4

1 に答える 1

0

アプリケーションサーバー/JMS実装は、単一のJMSキューマネージャー上の2つの接続での操作を含むグローバルトランザクションを1フェーズコミットトランザクションに最適化するのに適していますか(標準の調査と理解はこれが不可能であることを示しているようです)?

私の理解は次のとおりです。JMSは特別な種類のJCAコネクタです。通常、コネクタには、物理​​接続と一致する管理対象接続のプールが内部にあります。管理対象接続は、一度に1つのトランザクションにのみ関与できます(ただし、トランザクションは一時停止および再開できるため、少し複雑です)。Beanが取得するのは、接続ハンドルです。Beanが特定のトランザクション内から複数の接続ハンドルを取得する場合、ハンドルは同じ管理対象接続によってサポートされます。つまり、分散トランザクションを伴うべきではありません。

もちろん、それはコネクタとアプリサーバーの実装に依存します。JMSリソースを非XAとして構成して( XAサポートを有効/無効にできるオプションがあるはずです)、MDBでメッセージを受信して​​別のメッセージをキューに送信できるかどうかを確認することで、実際にこれを試すことができます。それは機能します、それは分散トランザクションが含まれないことを意味します。

注:一般的な最適化は「最後のリソースの最適化」です。これにより、分散トランザクションの参加者の1人が、最後のリソースとして使用することにより、実際にローカルの参加者になることができます。この最後の参加者は、それが分散トランザクションに属していることに気付くことはありません。

于 2012-08-31T07:28:25.480 に答える