Issue
this is my first post here so I apologize in advance if I don't respect formatting rules or other general rules.
I have a Spring JMS based client application that reads from a queue using multiple consumers. My constraints are: guaranteed redelivery in case of failure and message duplication detection.
Spring configuration
<bean id="jndiDestinationResolver" class="org.springframework.jms.support.destination.DynamicDestinationResolver" />
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<constructor-arg ref="MyConnectionFactory" />
<property name="destinationResolver" ref="jndiDestinationResolver" />
<property name="receiveTimeout" value="100" />
</bean>
<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="destinationResolver" ref="jndiDestinationResolver" />
<property name="connectionFactory" ref="MyConnectionFactory" />
<property name="destinationName" value="my_Queue" />
<property name="messageListener" ref="MyListener" />
<property name="maxConcurrentConsumers" value="10"/>
<property name="sessionTransacted" value="true"/>
</bean>
My listener code is something like:
protected void processTextMessage(TextMessage textMessage) { try { // process message } catch(Exception e) { try { sendTextMessage("my_Queue",correlationID, textMessage.getText()); } catch (JMSException e1) { log.error("Error writing message back to the queue!"); throw JmsUtils.convertJmsAccessException(e1); } } } protected void sendTextMessage(String queueName, final byte[] correlationID, String message) { jmsTemplate.convertAndSend(queueName, message, new MessagePostProcessor() { public Message postProcessMessage(Message message) throws JMSException { message.setJMSCorrelationIDAsBytes(correlationID); return message; } }); }
I made some local failure tests with ActiveMQ and re-sendings were ok (I noticed the redelivered flag to false). I also tried to stop brutally the application server during processing, and was able to check in that moment queue contained 1 message with redelivered=true.
Would this be a right approach to reach my goals?
I hope this would be transparent in respect to the JMS provider i will use (on production environents Websphere MQ is used). At the moment I would like to avoid just rollback the transaction by throwing an exception: i wish to reschedule my failed message like a new fresh message in the queue. For duplicate detection, I think inserting a business existence check would be enough.
Thanks in advance and best regards
Solution
Yes, that is the correct approach.
Answered By - Gary Russell
Answer Checked By - Timothy Miller (JavaFixing Admin)