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