2017-05-24 18 views
0

ActiveMQ(バージョン5.14.5)キューからJMSメッセージを消費するための簡単なSpringブートアプリケーション(Springブートバージョン1.5.3.RELEASE)があります。Spring JMSトランザクションのロールバック - メッセージがActiveMQからデキューされる

JMSトランザクションでメッセージが消費されるようにします。メッセージの消費中に例外が発生した場合、トランザクションはロールバックされ、メッセージはデキューされない(メッセージキューから取り出される)ことが期待されます。私はトランザクションがSpringログでロールバックされているのを見ることができますが、メッセージはまだActiveMQキューからデキューされています(6回の再配送試行後)。

何か指摘します。

@SpringBootApplication 
public class SpringJmsDemoApplication { 
public static void main(String[] args) { 
     SpringApplication.run(SpringJmsDemoApplication.class, args); 
    } 

    @Bean 
    public JmsListenerContainerFactory<?> myFactory(ConnectionFactory connectionFactory, 
      DefaultJmsListenerContainerFactoryConfigurer configurer) { 
     DefaultJmsListenerContainerFactory defaultJmsListenerContainerFactory = new DefaultJmsListenerContainerFactory(); 
     defaultJmsListenerContainerFactory.setTransactionManager(jmsTransactionManager(connectionFactory)); 
     defaultJmsListenerContainerFactory.setSessionTransacted(true); 
     defaultJmsListenerContainerFactory.setSessionAcknowledgeMode(Session.SESSION_TRANSACTED); 
     configurer.configure(defaultJmsListenerContainerFactory, connectionFactory); 
     return defaultJmsListenerContainerFactory; 
    } 

    @Bean 
    public PlatformTransactionManager jmsTransactionManager(ConnectionFactory connectionFactory) { 
     return new JmsTransactionManager(connectionFactory); 
    } 
} 

@Component 

パブリッククラスレシーバここ{

@JmsListener(destination = "mailbox", containerFactory = "myFactory") 
@Transactional 
public void receiveMessage(String email) { 
    System.out.println("Received <" + email + ">"); 
    throw new RuntimeException("nooo"); 
} 

}

ログである:ActiveMQのメッセージ再に従って

2017-05-24 09:51:59.865 DEBUG 8972 --- [DefaultMessageListenerContainer-1] o.s.j.connection.JmsTransactionManager : Created JMS transaction on Session [ActiveMQSession {id=ID:D6C0B8467A518-58248-1495590693980-1:32:1,started=false} [email protected]] from Connection [ActiveMQConnection 
2017-05-24 09:51:59.867 DEBUG 8972 --- [DefaultMessageListenerContainer-1] o.s.j.l.DefaultMessageListenerContainer : Received message of type [class org.apache.activemq.command.ActiveMQTextMessage] from consumer [ActiveMQMessageConsumer { value=ID:D6C0B8467A518-58248-1495590693980-1:32:1:1, started=true }] of transactional session [ActiveMQSession {id=ID:D6C0B8467A518-58248-1495590693980-1:32:1,started=true} [email protected]] 
2017-05-24 09:51:59.867 DEBUG 8972 --- [DefaultMessageListenerContainer-1] o.s.j.l.DefaultMessageListenerContainer : Rolling back transaction because of listener exception thrown: org.springframework.jms.listener.adapter.ListenerExecutionFailedException: Listener method 'public void com.anz.markets.springjmsdemo.Receiver.receiveMessage(java.lang.String)' threw exception; nested exception is java.lang.RuntimeException: nooo 
2017-05-24 09:51:59.867 WARN 8972 --- [DefaultMessageListenerContainer-1] o.s.j.l.DefaultMessageListenerContainer : Execution of JMS message listener failed, and no ErrorHandler has been set. 

org.springframework.jms.listener.adapter.ListenerExecutionFailedException: Listener method 'public void com.anz.markets.springjmsdemo.Receiver.receiveMessage(java.lang.String)' threw exception; nested exception is java.lang.RuntimeException: nooo 
    at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:112) ~[spring-jms-4.3.8.RELEASE.jar:4.3.8.RELEASE] 
    at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:69) ~[spring-jms-4.3.8.RELEASE.jar:4.3.8.RELEASE] 
    at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:721) ~[spring-jms-4.3.8.RELEASE.jar:4.3.8.RELEASE] 
    at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:681) ~[spring-jms-4.3.8.RELEASE.jar:4.3.8.RELEASE] 
    at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:651) ~[spring-jms-4.3.8.RELEASE.jar:4.3.8.RELEASE] 
    at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:317) [spring-jms-4.3.8.RELEASE.jar:4.3.8.RELEASE] 
    at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:235) [spring-jms-4.3.8.RELEASE.jar:4.3.8.RELEASE] 
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1166) [spring-jms-4.3.8.RELEASE.jar:4.3.8.RELEASE] 
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1158) [spring-jms-4.3.8.RELEASE.jar:4.3.8.RELEASE] 
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1055) [spring-jms-4.3.8.RELEASE.jar:4.3.8.RELEASE] 
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_72] 
Caused by: java.lang.RuntimeException: nooo 
    at com.anz.markets.springjmsdemo.Receiver.receiveMessage(Receiver.java:12) ~[classes/:na] 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_72] 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_72] 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_72] 
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_72] 
    at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:180) ~[spring-messaging-4.3.8.RELEASE.jar:4.3.8.RELEASE] 
    at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:112) ~[spring-messaging-4.3.8.RELEASE.jar:4.3.8.RELEASE] 
    at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:104) ~[spring-jms-4.3.8.RELEASE.jar:4.3.8.RELEASE] 
    ... 10 common frames omitted 

2017-05-24 09:51:59.868 DEBUG 8972 --- [DefaultMessageListenerContainer-1] o.s.j.connection.JmsTransactionManager : Transactional code has requested rollback 
2017-05-24 09:51:59.868 DEBUG 8972 --- [DefaultMessageListenerContainer-1] o.s.j.connection.JmsTransactionManager : Initiating transaction rollback 
2017-05-24 09:51:59.868 DEBUG 8972 --- [DefaultMessageListenerContainer-1] o.s.j.connection.JmsTransactionManager : Rolling back JMS transaction on Session [ActiveMQSession {id=ID:D6C0B8467A518-58248-1495590693980-1:32:1,started=true} [email protected]] 
+0

それは、 – kb1

+0

ActiveMQブローカログをチェックしてブローカがメッセージをロールバックするのを見ることができますが、ロールバックの効果は確認できます – kb1

+0

ActiveMQ Brokerを設定して、メッセージがDead Lにルーティングされないようにすることは可能ですか? etter Queueですが、トランザクションのロールバックの場合は元のキューにエンキューされたままですか?アプリケーション永続ストア(db)が停止しているシナリオでは、メッセージを取引の手紙のキューに移動するのではなく、待ち行列に入れたままにすることをお勧めします。 – kb1

答えて

0

ここ

は、アプリケーション・コードでありますディレクティブ(http://activemq.apache.org/message-redelivery-and-dlq-handling.html)に移動します。

"ActiveMQのデフォルトのデッドレターキューはActiveMQ.DLQと呼ばれています。すべての配信不能メッセージがこのキューに送信され、管理が困難になる可能性があります。したがって、activemq.xmlコンフィギュレーションファイルの宛先ポリシーマップにindividualDeadLetterStrategyを設定すると、特定のキューまたはトピックに対して特定のデッドレターキュープレフィックスを指定できます。あなたのような場合

してください「の下の例に示すように、すべてのキューが、自分のデッドレターキューを取得するように、キューにあなたindividualDeadLetterStrategyactivemq.xmlを拡張し、ワイルドカードを使用して、この戦略を適用することができます。

関連する問題