DefaultMessageListenerContainer訊息應答方式
JMS標準支援的訊息應答模式有下面幾種:
AUTO_ACKNOWLEDGE:自動應答,預設的應答方式
CLIENT_ACKNOWLEDGE:客戶端應答,應答由應用程式在接收到訊息後觸發
DUPS_OK_ACKNOWLEDGE:儘量不要使用,如果使用這種方式,應用程式需要考慮處理訊息重複問題
SESSION_TRANSACTED:事務應答
使用MessageConsumer來接收訊息時不管是AUTO_ACKNOWLEDGE還是CLIENT_ACKNOWLEDGE,只要發生了異常,訊息都會進行jms.redeliveryPolicy.maximumRedeliveries配置數量的訊息重發重試,如果訊息無法傳送則會送到Dead-Letter佇列中,但是DefaultMessageListenerContainer在這方面的處理卻與標準的應答不相同,使用DefaultMessageListenerContainer來接收訊息時,如果採用AUTO_ACKNOWLEDGE的應答方式,那麼訊息不會重發,筆者建議使用CLIENT_ACKNOWLEDGE這種模式,這種模式發生異常時則會進行訊息重發,而且無需應用程式應答訊息,因為DefaultMessageListenerContainer已經替我們完成了訊息的應答,下面是相關程式碼:
AbstractMessageListenerContainer類
protected void commitIfNecessary(Session session, Message message) throws JMSException {
// Commit session or acknowledge message.
if (session.getTransacted()) {
// Commit necessary - but avoid commit call within a JTA transaction.
if (isSessionLocallyTransacted(session)) {
// Transacted session created by this container -> commit.
JmsUtils.commitIfNecessary(session);
}
}
else if (message != null && isClientAcknowledge(session)) {
message.acknowledge();
}
}
JmsAccessor類
protected boolean isClientAcknowledge(Session session) throws JMSException {
return (session.getAcknowledgeMode() == Session.CLIENT_ACKNOWLEDGE);
}
從上面程式碼可以看出,DefaultMessageListenerContainer會對CLIENT_ACKNOWLEDGE應答模式自動確認