相信經過了解,基本使用activemq後,大家一定知道隊列裏面有ACK模式,他的類型有以下幾種
1、AUTO_ACKNOWLEDGE = 1 自動確認
2、CLIENT_ACKNOWLEDGE = 2 客戶端手動確認
3、DUPS_OK_ACKNOWLEDGE = 3 自動批量確認
4、SESSION_TRANSACTED = 0 事務提交併確認
5、INDIVIDUAL_ACKNOWLEDGE = 4 單條消息確認(自定義ACK_MODE)
使用方式一般有
1、使用連接創建session
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
2、spring中配置
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory"></property>
<property name="defaultDestination" ref="destination"></property>
<property name="messageConverter" ref="jmsMessageConverter"></property>
<property name="sessionAcknowledgeMode" value="2" />
</bean>
注意:當我們只配置了這些,以爲在消費者出獲取消息調用message.acknowledge();方法就能控制消息的消費,很明顯,不行!
查閱資料你會發現,當你獲取消息的時候,默認的獲取方法裏面沒有走你的這些配置直接就消費了消息,所以就達不到我們想要的效果,手動控制消費。所以,我們需要重寫一個方法手動獲取,但是帶上自己的參數。
- /**
- * 接收消息
- * @param session
- * @param consumer
- * @param autoAcknowledge 是否開啓手動消費
- * @return
- * @throws JMSException
- */
- protected Message doReceive(Session session, MessageConsumer consumer,Boolean autoAcknowledge) throws JMSException {
- try {
- this.consumer = consumer;
- //Use transaction timeout (if available).
- long timeout = 1000;
- Message message = doReceive(consumer, timeout);
- if (session.getTransacted()) {
- // Commit necessary - but avoid commit call within a JTA transaction.
- // 如果開啓了jta事物,那麼不會進行提交,jta事物會直接覆蓋掉session事物
- if (isSessionLocallyTransacted(session)) {
- // Transacted session created by this template -> commit.
- //創建事物回話
- JmsUtils.commitIfNecessary(session);
- }
- }
- //autoAcknowledge如果爲真,不進行自動確認
- else if (isClientAcknowledge(session) && !autoAcknowledge) {
- // Manually acknowledge message, if any.
- if (message != null) {
- message.acknowledge();
- }
- }
- return message;
- }
- finally {
- consumer = null;
- }
- }
- /**
- * 由於上面的doReceive(Session session, MessageConsumer consumer,Boolean autoAcknowledge)需要調用這個方法,
- * 而在父類裏面這個方法是私有的,所以直接拷貝下來了
- * @param consumer
- * @param timeout
- * @return
- * @throws JMSException
- */
- private Message doReceive(MessageConsumer consumer, long timeout) throws JMSException {
- if (timeout == RECEIVE_TIMEOUT_NO_WAIT) {
- return consumer.receiveNoWait();
- }
- else if (timeout > 0) {
- return consumer.receive(timeout);
- }
- else {
- return consumer.receive();
- }
- }
原文地址:http://blog.csdn.net/yueding_h/article/details/54944254