4

キューからメッセージを消費し、いくつかの URL に HTTP 呼び出しを送信する Java クラスがあります。私はGoogleとstackoverflowでいくつかの検索を行いました(問題について言及しているソースを見逃していたら本当に申し訳ありません)が、 setRollbackOnly 呼び出しに関する詳細は何も見つかりませんでした.

私の質問は...ロールバックした場合、キューから消費されたメッセージは残りのキューをブロックし、正常に処理されるか、現在のキューの最後に再キューされるまでループしますか?

キューから消費して HTTP 呼び出しを送信するために使用するコードは以下のとおりで、アプリケーション全体が Glassfish サーバーで実行されています。

public クラス RequestSenderBean は MessageListener を実装します
{
  @リソース
  プライベート MessageDrivenContext mdbContext;

  public RequestSenderBean(){}

  public void onMessage(最終メッセージ メッセージ)
  {
    試す
    {
      if(ObjectMessage のメッセージ インスタンス)
      {

          文字列 responseOfCall=sendHttpPost(URL, PARAMS_FROM_MESSAGE);

          if(responseOfCall.startsWith("成功"))
          {
            //すべて問題ありません。いくつかのことを行ってください
          }
          else if(responseOfCall.startsWith("Failure"))
          {
            //失敗、他のことをする
          }

    }
    catch (最終的な例外 e)
    {
      e.printStackTrace();
      mdbContext.setRollbackOnly();
    }
  }
}
4

1 に答える 1

5

これは、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 チュートリアルとエンタープライズ統合パターンの本を読むことをお勧めします。この本では、メッセージングの概念が詳細に説明されており、製品やテクノロジにとらわれません。

于 2013-09-16T08:23:57.150 に答える