3

例外がスローされた後、または session.rollback() が呼び出された後に、Spring の DefaultMessageListenerContainer クラスをセットアップしてメッセージを再配信しようとしています。また、これを Glassfish 3.1.2 Web プロファイルで実行しようとしています。

SessionAwareMessageListener の onMessage() メソッドで session.rollback() を呼び出すと、次のようなメッセージで例外が発生します: MessageDispatcher - [C4024]: セッションは処理されません。 ActiveMQ ではこの問題は見られませんが、もちろん、アプリケーション サーバーで使用していないため、その構成は異なります。

ここで誰かがこれを機能させましたか?私の構成は次のとおりです。

<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
    <property name="environment">
        <props>
            <prop key="java.naming.factory.initial">com.sun.enterprise.naming.SerialInitContextFactory</prop>
            <prop key="java.naming.provider.url">${jms.jndicontext.url}</prop>
            <prop key="java.naming.factory.state">com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl</prop>
            <prop key="java.naming.factory.url.pkgs">com.sun.enterprise.naming</prop>
        </props>
    </property>
</bean>

<bean id="jmsConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiTemplate" ref="jndiTemplate" />
    <property name="jndiName" value="${jms.connection.factory}" />
</bean>

<bean id="jmsTemplate"
      class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory" ref="jmsConnectionFactory"/>
    <property name="defaultDestination" ref="jmsServiceQueue"/>
</bean>

<bean id="jmsServiceProducer"
      class="net.exchangesolutions.services.messaging.service.jms.JmsMessageServiceProducerImpl">
    <property name="serviceTemplate" ref="jmsTemplate"/>
    <property name="serviceDestination" ref="jmsServiceQueue"/>
</bean>

<bean id="myMessageListener"
      class="com.myorg.jms.MessageDispatcher"/>


<bean id="jmsServiceContainer"
   class="org.springframework.jms.listener.DefaultMessageListenerContainer">
   <property name="connectionFactory" ref="jmsConnectionFactory"/>
   <property name="destination" ref="jmsServiceQueue"/>
   <property name="messageListener" ref="myMessageListener"/>
   <property name="errorHandler" ref="jmsErrorHandler" />
   <property name="receiveTimeout" value="180000"/>
   <property name="concurrentConsumers" value="1"/>
   <property name="cacheLevelName" value="CACHE_NONE"/>
   <property name="pubSubNoLocal" value="true"/>
   <property name="sessionTransacted" value="true"/>
   <property name="sessionAcknowledgeMode" value="2" />
   <property name="transactionManager" ref="jmsTransactionManager"/>
</bean>

<bean id="jmsTransactionManager" class="org.springframework.jms.connection.JmsTransactionManager">
    <property name="connectionFactory" ref="jmsConnectionFactory"/>
</bean>
4

1 に答える 1

3

を設定するacknowledge="auto"と、リスナーの実行前にメッセージが確認されるため、メッセージはキューから削除されます。

また、コードに次の変更を加えることで、Spring アプリケーションで DLQ シナリオを実現しました。

まず、acknowledge="transacted" を設定します (例外がスローされた場合に再配信を保証し、リスナーの実行が成功した場合に Trans 確認応答が必要なため)。

<jms:listener-container container-type="default" connection-factory="connectionFactory" acknowledge=" transacted">

次に、 を投げたいのでJMSException、 を実装していSessionAwareMessageListenerます。

public class MyMessageQueueListener implements SessionAwareMessageListener {
    public void onMessage( Message message , Session session ) throws JMSException {
        //DO something
        if(success){
            //Do nothing – so the transaction acknowledged
        } else {
            //throw exception - So it redelivers
            throw new JMSException("..exception");
        } 
    }
}

私はこれをテストしました。これはうまくいっているようです。

于 2012-12-11T02:00:54.687 に答える