2014-06-19 111 views
1

我正在使用WerbLogic 10.3.5和Spring 3.0來實現JMS隊列。我有以下Spring配置:Spring/WebLogic - 失敗時未重新發送JMS消息

<!-- JMS Configuration --> 
<bean id="paymentlistener" class="com.myproject.service.impl.PaymentListener"/> 

<bean id="paymentlistenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer"> 
    <property name="concurrentConsumers" value="10"/> 
    <property name="connectionFactory" ref="paymentConnectionFactory"/> 
    <property name="destination" ref="paymentQueue"/> 
    <property name="messageListener" ref="paymentlistener"/> 
</bean> 

<bean id="paymentQueue" class="org.springframework.jndi.JndiObjectFactoryBean"> 
    <property name="jndiName" value="jms/paymentResponseHandlerQueue"/> 
    <property name="jndiTemplate" ref="jndiTemplate"/> 
</bean> 

<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate"> 
    <property name="environment"> 
     <props> 
      <prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</prop> 
      <prop key="java.naming.provider.url">t3://localhost:7001</prop> 
     </props> 
    </property> 
</bean> 

<bean id="paymentConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean"> 
    <property name="jndiTemplate" ref="jndiTemplate"/> 
    <property name="jndiName" value="jms/paymentResponseHandlerConnectionFactory"/> 
</bean> 

<bean id="jmsDestinationResolver" class="org.springframework.jms.support.destination.JndiDestinationResolver"> 
    <property name="jndiTemplate" ref="jndiTemplate"/> 
    <property name="cache" value="true"/> 
</bean> 

<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"> 
    <property name="connectionFactory" ref="paymentConnectionFactory"/> 
    <property name="destinationResolver" ref="jmsDestinationResolver"/> 
    <property name="defaultDestination" ref="paymentQueue"/> 
    <property name="sessionAcknowledgeModeName" value="DUPS_OK_ACKNOWLEDGE"/> 
    <property name="sessionTransacted" value="true"/> 
</bean> 

我的消息的創建代碼如下所示:

MessageCreator messageCreator = new MessageCreator() { 
     public Message createMessage(Session session) throws JMSException { 
       logger.debug("Session ack mode: " + session.getAcknowledgeMode()); 
       return session.createObjectMessage(payment); 
     } 
    }; 


    jmsTemplate.send("jms/paymentResponseHandlerQueue", messageCreator); 

我的聽衆是這樣的:正在正確創建

@Override 
public void onMessage(Message message) { // , Session session 
if (!(message instanceof ObjectMessage)) { 
    throw new IllegalStateException("The PaymentListener queue expects an object message"); 
} 

ObjectMessage objectMessage = (ObjectMessage) message; 

try { 
    logger.debug("Is Message redelivered:" + objectMessage.getJMSRedelivered()); 

    if (objectMessage.getObject() instanceof CreditCardPaymentDTO) { 

     logger.debug("Object is of type CreditCardPaymentDTO"); 

     // The user that just logged in 
     CreditCardPaymentDTO payment = (CreditCardPaymentDTO) objectMessage.getObject();    
     otpCollectorDAO.savePayment(payment); 
    } 
} catch (JMSException e) { 
    logger.error(e); 
    throw new RuntimeException(e); 
} catch (PaymentResponseException e) { 
    logger.error(e); 
    throw new RuntimeException(e); 
} 
} 

的消息,並且我的監聽器的onMessage()方法被調用,但是如果邏輯失敗並且我拋出一個RuntimeException(),則該消息不會被重新傳遞。我已經嘗試了上述代碼的許多細微變化(例如,設置sessionAcknowledgeModeName = SESSION_TRANSACTED並顯式回滾事務),但是消息從不重新排隊。獲取失敗消息重新傳遞的訣竅是什麼?

+0

你有沒有嘗試爲'DefaultMessageListenerContainer'設置'sessionTransacted'爲「true」? –

+0

就是這樣。如果你提供這個答案,我會接受它。謝謝! – freecouch

+0

:-)很酷,很高興現在正在工作。 –

回答

2

我相信你需要設置sessionTransactedtrueDefaultMessageListenerContainer

<bean id="paymentlistenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer"> 
    ... 
    <property name="sessionTransacted" value="true"/> 
</bean> 

你可以找到here相關的參考文檔。