2011-12-06 10 views
3

メッセージ肯定応答を確実にする方法は、肯定応答がjmsブローカで呼び出されたメッセージまでのメッセージのみを削除します。 現在、私は、jmsキューから消費し、それを部分的に処理するシステムを持っています。後でこれらのメッセージのバッチは、別のスレッドによって保持されます。私は今メッセージで確認する必要があります。しかし、問題は私がメッセージを消費するのをやめなければならないことです。それ以外の場合、以前に受信したメッセージを確認すると、受信された他のすべてのメッセージも認識されます。メッセージが確認されるまでのJmsメッセージの了解

つまり、キューに10個のメッセージがあるとします。私はそれらのうちの7つを消費し、5番目のメッセージで了承します。これにより、消費者がキューから受信した7つのメッセージがすべて削除されます。キューから5番目のメッセージまでは、メッセージを確認して削除するしか方法はありません。

EDIT:私は2つのセッションを作成し、異なるセッションからの消費が、(Apacheのqpidの少なくともと共に)、これは矛盾実行しようとしています。矛盾する言い方をすれば、テスト中に、ある消費者がメッセージを受け取ることができる一方で、他の人はどれくらい待っても、まったく受信しないことがあります。これは解決策として私のために働いていただろうが、矛盾のためにこれを解決策として使うことはできない。

+0

使用しているメッセージプロバイダーが指定されていません。しかし、私が知る限り、多くのメッセージングプロバイダはランダムなメッセージ確認を許可していません。あなたが1つのメッセージを確認したら、その時点までに受信したすべてのメッセージも承認され、キューから削除されます。 – Shashi

+0

私はapache qpidを使用しますが、ランダムな確認はしません。その前のすべてのメッセージがクリアされてもOKですが、それ以上のメッセージが受信された場合は、それらも削除されます。 – Raks

答えて

4

私はこの投稿が古いと理解していますが、この回答は後でそれにつきまとう人に恩恵を受けるはずです。あなたが承認したいどのメッセージのきめの細かい制御を希望した場合

は、individualは方法はあなたを助けるべき認めます。この承認モードを使用すると、セッション内の個々のメッセージを確認できます。承認されていないメッセージは再配信されます。

これは仕様の一部ではありませんが、ほとんどのキュープロバイダは仕様外でサポートしています。より多くの柔軟性を高めるため

Oracle

、メッセージキューを使用すると、JMS クライアント承認モードをカスタマイズできます。クライアント肯定応答モードでは、クライアント は、メッセージオブジェクトの 肯定応答()メソッドを呼び出して、メッセージ消費を明示的に確認します。

の標準的な動作は、このメソッドは は、メソッドが呼び出された最後の時間 ので、セッション内のすべての消費者によって消費されたことをすべてのメッセージを確認するために、セッションを引き起こすことがあります。 (つまり、セッションは関係なく、 がそれらを消費者の、現在の メッセージとすべての以前に未確認のメッセージを認めています。)

をJMSで指定された標準的な動作に加えて、メッセージキュー は、あなたがクライアント承認モードを使用することができます 時に1つのメッセージを確認します。

public interface com.sun.messaging.jms.Message { 
      void acknowledgeThisMessage() throws JMSException; 
      void acknowledgeUpThroughThisMessage() throws JMSException; 
} 

ActiveMQ

一つは、他の 例えば、あまりにも有用であろうモードを認める想像することができます:Message.acknowledgeは() メッセージのみを認めるだろうCONSUMER_ACKNOWLEDGEは、特定のMessageConsumer上に受信、 またはCONSUMER_CHECKPOINT_ACKNOWLEDGEここで、Message.acknowledge()は のメッセージまで受信したメッセージのみを確認応答します。このメソッドが呼び出されました。

しかし、すべてのこれらの様々な異なる可能性に着手せず、 はそれだけでINDIVIDUAL_ACKNOWLEDGE モードを追加することを検討することは可能でしょうか?これだけで、マルチスレッドアプリケーション が必要な動作を達成することが可能になります。

connection.createQueueSession(false, ActiveMQSession.INDIVIDUAL_ACKNOWLEDGE); 

私は個人的にQPIDを使用していない、しかし、個々のメッセージACKが可能であるという事実にdocumentation hints

Examples 
    # acknowledge all received messages 
    session.acknowledge 

    # acknowledge a single message 
    session.acknowledge :message => message 

バッチ処理中に、受信して処理される各メッセージを確認できます。例外が発生した場合は、メッセージを確認しないでください。

1

メッセージを確認すると、そのメッセージとそのメッセージの前に受信した他のすべてのメッセージが削除されます。アプリケーションがまだ受信していないメッセージは削除しないでください。どのようにメッセージを承認しているかをアプリケーションで確認したい場合があります。

+0

問題は、コンシューマが受信したすべてのメッセージが削除され、そのメッセージに依存していないことです。私はその後にもっとメッセージを受け取っているかもしれないが、あるメッセージを取り除くだけのものを実装したい。これは、バッチ処理でメッセージを処理し、バッチ処理が完了するたびに、そのバッチまで確認する必要があるため、必要です。そしてこのバッチ処理は時間がかかりますので、私は並行してメッセージを受信し続けます – Raks

+0

いいえ、それは不可能です。 1つのメッセージが拒否されると、受信したすべてのメッセージが削除されます。代替案を見る必要があるかもしれません。 – Shashi

関連する問題