1. 程式人生 > >DefaultMessageListenerContainer訊息應答方式

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應答模式自動確認