1.爲什麼要用事務?
爲什麼commit之後,不會有持久的消息重新傳送呢?
原因在於commit操作會自動將爲簽收確認的消息進行簽收確認,如果是當前接收但未簽收確認的消息,都會被確認處理。因而在commit之後不會有持久化的消息出現。
2.activeMQ支持的事務:
ActiveMQ有支持兩種事務,
- JMS transactions - the commit() / rollback() methods on a Session (which is like doing commit() / rollback() on a JDBC connection)
- XA Transactions - where the XASession acts as an XAResource by communicating with the Message Broker, rather like a JDBC Connection takes place in an XA transaction by communicating with the database.
在支持事務的session中,producer發送message時在message中帶有transaction ID。broker收到message後判斷是否有transaction ID,如果有就把message保存在transaction store中,等待commit或者rollback消息。所以ActiveMq的事務是針對broker而不是producer的,不管session是否commit,broker都會收到message。
如果producer發送模式選擇了persistent,那麼message過期後會進入死亡隊列。在message進入死亡隊列之前,ActiveMQ會刪除message中的transaction ID,這樣過期的message就不在事務中了,不會保存在transaction store中,會直接進入死亡隊列。具體刪除transaction ID的地方是在:org.apache.activemq.util.BrokerSupport的doResend,將transaction ID保存在了originalTransactionID中,刪除了transaction ID。
在下面的介紹中我用的是JMS transactions.
JMS transactions事務的配置:
①建立JMS事務,並引入關聯鏈接事務。
②.設置一個jmsTamplat,並關聯監聽容器。
- <!-- jms事務 -->
- <bean id="jmsTransactionManager"
- class="org.springframework.jms.connection.JmsTransactionManager">
- <property name="connectionFactory" ref="connectionFactory" />
- </bean>
- <tx:annotation-driven transaction-manager="jmsTransactionManager" />
- <!-- 消息監聽容器 消息接收監聽器用於異步接收消息 -->
- <bean id="jmsContainerOne" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
- <property name="connectionFactory" ref="connectionFactory" />
- <property name="destination" ref="destinationOne" />
- <property name="messageListener" ref="consumerMessageListenerOfOne" />
- <!-- <property name="sessionTransacted" value="true"/> --> <!-- 給listener添加事務,只負責接收消息的回滾 (有了transactionManager就不用這個了,這個功能不全) 設置後好像並沒有起作用 不知道爲啥 -->
- <!-- <property name="transactionManager" ref="jtaTransactionManager"/> --> <!-- 接收消息和數據庫訪問處於同一事務中 jta -->
- <property name="transactionManager" ref="jmsTransactionManager" /> <!--jms事務 -->
- <property name="sessionAcknowledgeMode" value="4"></property> <!-- 應答模式是 INDIVIDUAL_ACKNOWLEDGE http://blog.csdn.net/yueding_h/article/details/54944254 -->
- <!-- ActiveMQ:設置多個並行的消費者 -->
- <property name="concurrency" value="2-3" />
- </bean>
- session.rollback();
- public void onMessage(Message message, Session session) {
- TextMessage textMsg = (TextMessage) message;
- try {
- System.out.println(1);
- String endStr = textMsg.getText();
- Integer endInt = Integer.parseInt(endStr);
- System.out.println("消息:==="+endInt);
- //只要被確認後 就會出隊,接受失敗沒有確認成功,會在原隊列裏面
- textMsg.acknowledge();
- } catch (Exception e) {
- try {
- session.rollback();
- System.out.println("測試回滾");
- e.printStackTrace();
- System.out.println("異常信息是:===:" + e.getMessage());
- }
- }
待我詳細瞭解JtaTransactionManager 後,再說吧。