2

Spring アプリを持っています。JMS メッセージ グループを使用して、特定のブロック (および同じトランザクションなど) で JMS メッセージを処理したいと考えています。基本的に、5 つの関連するイベントがあるとします。同じ連続しJMSTemplateた値でそれらを送信する があります。JMSXGroupIDJMSXGroupSeq

次にMessageProcessorService、Spring で次のように定義します。

<bean id="messageProcessorService" class="x.y.z.MessageProcessorService"/>
<jms:listener-container connection-factory="pooledJmsConnectionFactory" concurrency="5" >
    <jms:listener destination="messages.queue" ref="messageProcessorService" />
</jms:listener-container>

MessageProcessorServiceは標準でシンプルです:

@Service
public class MessageProcessorService implements MessageListener {

public void onMessage(Message msg) { ... }
}

問題は、onMessage が一度に 1 つのメッセージしか取得しないためです。特定のグループの 5 つのメッセージをすべて取得して処理を開始するにはどうすればよいですか?

グループの終わりを示すために負の値を使用できることを知っているのでJMSXGroupSeq、メッセージの小さなリストを保持してメッセージを調べ、JMSXGroupSeqそれが -1 のときにグループ全体を処理できると考えていましたが、それは少し思われますハッキーで、スレッドセーフかどうかはわかりません(複数のスレッドを並行して処理する必要があることは間違いありません)。

Spring/JMS/ActiveMQ で以前にこのようなことをした人はいますか?

4

2 に答える 2

0

素晴らしい質問です。メッセージ グループは一部のタスクには適していますが、メッセージ リスナーには適切にマッピングされません。

メッセージのメモリにリストを保持するために、あなたのアプローチに行くことができます。プロトタイプ スコープで Listener Bean を作成する場合、スレッドの安全性は問題になりません。

<bean id="messageProcessorService" class="x.y.z.MessageProcessorService" scope="prototype"/>

http://static.springsource.org/spring/docs/3.0.7.RELEASE/reference/beans.html#beans-factory-scopes-prototype

クラスで受信したメッセージの内部リストを保持する必要があるだけで、それらはそのスレッドで一意になります。

これは、トランザクションの要件が何であるかによって少し異なります。メッセージグループ全体でトランザクションをコミットする必要がありますか? 次に、いつコミットし、いつコミットしないかを追跡する必要があります。IBM はこの例をリスト 5 に示しています (ただし ActiveMQ は使用していません) これは Spring ではなく、単純な MDB です。ただし、ActiveMQ と同じように動作するとは言えませんので、保証はしません。

于 2012-08-30T20:46:40.190 に答える