activemq 事務--遇到異常始終回滾

 

轉自:https://blog.csdn.net/lsm135/article/details/74945116

1. 啓用消息事務
<property name="sessionTransacted" value="true"/>




2. 當消息在消費的時候,如果用戶程序拋出Exception,則消息會回滾重傳(mq裏面的未消費消息數目不變), 
spring 的activemq默認最多重傳6次, 超過6次,即使拋出了異常,這個消費仍然被消費不可回滾。
jms.redeliveryPolicy.maximumRedeliveries=6(默認)
我們可以設置brokerURL裏面的jms.redeliveryPolicy.maximumRedeliveries=-1
-1表示可以無限次重傳,0表示不重傳。


注意中間要用 html轉移符 &amp;     (就是url查詢字符串裏的&字符)

3.消息隊列回滾的觸發--程序本身運行異常,比如數據庫操作異常,如果自己用程序去檢查數據庫更新條數,如果小於1,程序可以人爲編寫代碼,人爲

拋出一個RuntimeException. 這兩種情況都能觸發消息的rollback

如在onMesssage()裏,或者內部嵌套的方法裏

 

throw new RuntimeException("Update DB failed.");

 

 

 

最終配置文件如下

appContext.xml

 


 
  1. <?xml version="1.0" encoding="UTF-8"?>

  2. <beans xmlns="http://www.springframework.org/schema/beans"

  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"

  4. xsi:schemaLocation="

  5. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

  6. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

  7.  
  8. <import resource="mybatisContext.xml" />

  9. <import resource="shardingContext.xml" />

  10.  
  11. <!-- 配置JMS連接工廠 -->

  12. <!-- 測試環境 -->

  13. <bean id="jmsFactory" class="org.apache.activemq.spring.ActiveMQConnectionFactory">

  14. <property name="brokerURL"

  15. value="failover:(tcp://10.0.0.9:61616)?randomize=false&timeout=3000&initialReconnectDelay=100&jms.useAsyncSend=true&jms.redeliveryPolicy.maximumRedeliveries=-1" />

  16. </bean>

  17. <!-- 配置JMS模版 -->

  18. <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">

  19. <property name="connectionFactory">

  20. <!-- lets wrap in a pool to avoid creating a connection per send -->

  21. <bean class="org.springframework.jms.connection.SingleConnectionFactory">

  22. <property name="targetConnectionFactory">

  23. <ref local="jmsFactory" />

  24. </property>

  25. </bean>

  26. </property>

  27. </bean>

  28.  
  29. <!-- MQ監聽者 -->

  30. <bean id="smsSendForMQListener"

  31. class="org.springframework.jms.listener.DefaultMessageListenerContainer">

  32. <property name="connectionFactory">

  33. <ref bean="jmsFactory" />

  34. </property>

  35. <property name="destinationName">

  36. <value>DistributePics</value>

  37. </property>

  38. <property name="messageListener">

  39. <ref bean="saveListener" />

  40. </property>

  41. <!-- mq事務控制,如果拋異常了就回滾消息 -->

  42. <property name="sessionTransacted" value="true"/>

  43.  
  44. </bean>

  45.  
  46. <!-- Spring MVC -->

  47. <context:component-scan base-package="com.x.service"></context:component-scan>

  48. <context:component-scan base-package="com.x.controller.**"></context:component-scan>

  49. <context:component-scan base-package="com.x.listener"></context:component-scan>

  50. <context:component-scan base-package="com.x.spring"></context:component-scan>

  51. </beans>

 

 

java程序如下:

 

 


 
  1. package com.x.imgapp.listener;

  2.  
  3. import java.util.concurrent.Future;

  4.  
  5. import javax.jms.JMSException;

  6. import javax.jms.Message;

  7. import javax.jms.MessageListener;

  8. import javax.jms.ObjectMessage;

  9. import javax.jms.BytesMessage;

  10.  
  11. import org.springframework.stereotype.Component;

  12.  
  13. import com.x.imgapp.common.model.MsgBean;

  14. import com.x.imgapp.concurrent.AppExecutor;

  15. import com.x.imgapp.concurrent.MoveThread;

  16.  
  17. import org.apache.activemq.command.ActiveMQBytesMessage;

  18. import org.apache.activemq.util.ByteSequence;

  19. import org.slf4j.Logger;

  20. import org.slf4j.LoggerFactory;

  21.  
  22. /**

  23. *

  24. * @author frank.liu

  25. *

  26. */

  27. @Component("saveListener")

  28. public class SaveDBListener implements MessageListener {

  29. private static final Logger logger = LoggerFactory.getLogger(SaveDBListener.class);

  30. private static Long receiveCount = 0L;

  31.  
  32. @Override

  33. public void onMessage(Message message) {

  34. logger.info("Step into onMessage()------------------------------->");

  35. ActiveMQBytesMessage msg = (ActiveMQBytesMessage) message;

  36. ByteSequence sequence = msg.getContent();

  37. String msgStr = new String(sequence.data);

  38. //

  39. // Future<Integer> future = AppExecutor.getExecutor().submit(new MoveThread(msgStr));

  40. logger.info("receiveCount:{}", ++receiveCount);

  41. throw new RuntimeException("Update DB failed.");

  42. }

  43. }

  44.  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章