これは、JMS/メッセージングの基本的な知識です。
キューは「負荷分散」シナリオを実装します。これにより、メッセージがキューにヒットし、キューから取り出されて 1 つのコンシューマーによって処理されます。コンシューマーの数を増やすと、そのキューの処理の潜在的なスループットが向上します。キュー上の各メッセージは、ただ 1 つのコンシューマーによって処理されます。
トピックはパブリッシュ/サブスクライブ セマンティクスを提供します。トピックのすべてのコンシューマーは、トピックにプッシュされたメッセージを受信します。
そのことを念頭に置いて、メッセージがデキューされて (トランザクション的に) コンシューマに渡されると、それが非同期の場合 (MDB の場合のように) キューの残りをブロックすることは決してありません。
Java EEチュートリアルが述べているように:
メッセージ消費
メッセージング製品は本質的に非同期です。メッセージの生成と消費の間に基本的なタイミングの依存関係はありません。ただし、JMS 仕様では、この用語をより正確な意味で使用しています。メッセージは、次の 2 つの方法のいずれかで消費できます。
同期: サブスクライバーまたは受信者は、 receive メソッドを呼び出して、宛先からメッセージを明示的にフェッチします。receive メソッドは、メッセージが到着するまでブロックしたり、指定された制限時間内にメッセージが到着しない場合にタイムアウトしたりできます。
非同期: クライアントは、メッセージ リスナーをコンシューマーに登録できます。メッセージ リスナーは、イベント リスナーに似ています。メッセージが宛先に到着するたびに、JMS プロバイダーはリスナーの onMessage メソッドを呼び出してメッセージを配信します。このメソッドは、メッセージの内容に作用します。
MessageListener
定義上非同期であるを使用しているため、キューまたはその後の処理をブロックしていません。
また、チュートリアルからは次のとおりです。
セッション Bean を使用してメッセージを生成し、同期して受信する
メッセージを生成したり同期的に受信したりするアプリケーションは、セッション Bean を使用してこれらの操作を実行できます。セッション Bean で JMS API を使用するアプリケーションの例では、ステートレス セッション Bean を使用してメッセージをトピックにパブリッシュします。
ブロッキング同期受信はサーバー リソースを占有するため、エンタープライズ Bean でこのような受信呼び出しを使用することは、プログラミングの良い方法ではありません。代わりに、時間指定同期受信を使用するか、メッセージ駆動型 Bean を使用してメッセージを非同期的に受信してください。ブロッキングおよび時間指定された同期受信の詳細については、「同期受信の例のクライアントの記述」を参照してください。
メッセージの失敗に関しては、キューの構成方法によって異なります。後で検査するために失敗したメッセージをプッシュするエラー キュー (Glassfish や Weblogic などのコンテナーの場合) を設定できます。あなたの場合、次のsetRollbackOnly
ように処理されるものを使用しています:
7.1.2 メッセージ駆動型 Bean のコーディング: MessageBean.java
メッセージ駆動型 Bean クラス MessageBean.java は、メソッド setMessageDrivenContext、ejbCreate、onMessage、および ejbRemove を実装します。onMessage メソッドは、TextListener.java のメソッドとほぼ同じで、着信メッセージを TextMessage にキャストし、テキストを表示します。唯一の大きな違いは、例外が発生した場合に MessageDrivenContext.setRollbackOnly メソッドを呼び出すことです。このメソッドは、メッセージが再配信されるようにトランザクションをロールバックします。
Java EE チュートリアルとエンタープライズ統合パターンの本を読むことをお勧めします。この本では、メッセージングの概念が詳細に説明されており、製品やテクノロジにとらわれません。