私はJMSサーバとしてActiveMqを、トランザクションマネージャとしてAtomikosを使用します。ActiveMqとAtomikosを使用してJMSメッセージを2回デキューしました
ActiveMq AdminのWebインターフェイスでは、1つのメッセージがエンキューされていますが、2(!)のメッセージはデキューされています。
ただし、jms consumerプロセス・メッセージは一度だけ処理に重複はありません。単純なSpring JmsTransactionManagerを使用すると、エンキューされたメッセージとデキューされたメッセージが1つずつあります。この問題は、Atomikos JTAトランザクションマネージャにのみ現れます。
何が問題ですか? Atomikosを2回デキューしないメッセージを表示しないように設定するにはどうすればよいですか?
私の設定は以下の通りです。チュートリアルとほぼ同じです。ところで、AtomikosのSpring統合の例はうまくいきますが、Spring 3.0を使用していますが、Spring 2.0を使用しています。
<bean id="activeMqXaConnectionFactory" class="org.apache.activemq.spring.ActiveMQXAConnectionFactory">
<property name="brokerURL" value="tcp://localhost:61616"/>
</bean>
<bean id="atomikosQueueConnectionFactory" class="com.atomikos.jms.QueueConnectionFactoryBean" init-method="init">
<property name="resourceName" value="xaMq"/>
<property name="xaQueueConnectionFactory" ref="activeMqXaConnectionFactory"/>
</bean>
<bean id="singleConnectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<property name="targetConnectionFactory" ref="atomikosQueueConnectionFactory"/>
</bean>
<bean id="jmsDefaultContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="singleConnectionFactory"/>
<property name="messageListener" ref="consumer"/>
<property name="concurrentConsumers" value="1"/>
<property name="destinationName" value="q.jtaxa"/>
<property name="receiveTimeout" value="3000"/>
<property name="recoveryInterval" value="5000"/>
<property name="transactionManager" ref="transactionManager"/>
<property name="sessionTransacted" value="true"/>
</bean>
<!-- Transactions -->
<!--Construct Atomikos UserTransactionManager, needed to configure Spring-->
<bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init"
destroy-method="close">
<!-- when close is called, should we force transactions to terminate or not? -->
<property name="forceShutdown" value="true"/>
</bean>
<!-- Also use Atomikos UserTransactionImp, needed to configure Spring -->
<bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
<property name="transactionTimeout" value="300"/>
</bean>
<!-- Configure the Spring framework to use JTA transactions from Atomikos -->
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager" ref="atomikosTransactionManager"/>
<property name="userTransaction" ref="atomikosUserTransaction"/>
<property name="nestedTransactionAllowed" value="true"/>
</bean>
Consumerクラスは次のとおりです。
@Component
public class Consumer implements MessageListener {
@Override
public void onMessage(Message message) {
if (message instanceof TextMessage) {
try {
TextMessage textMsg = (TextMessage) message;
System.out.println(" " + textMsg.getText());
} catch (JMSException ex) {
ex.printStackTrace();
}
}
}
}