Configuring retry behaviour for an MDB
ojacobson Jul 19, 2007 6:33 PMGood afternoon.
I'm working my way towards understanding JMS and MDBs and I've encountered a roadblock.
I have a very simple MDB which accepts one message out of X (it cheats on the EJB spect and keeps a per-instance "how many messages have I recieved" count) and "rejects" the rest with context.setRollbackOnly(). When X is large enough, JBoss gives up on re-sending the message before the next "accept message" state comes up and drops the message in the DLQ.
What I want to do is instruct JBoss to retry the message indefinitely, accepting the risk of a poison message blocking any further messages from being processed. If possible I'd also like the retries to be delayed a few seconds, rather than being re-delivered immediately after transaction rollback.
What configuration changes do I need to make to have at least one of those effects?
I have the following dead-simple MDB implementation:
package xxx; import javax.annotation.Resource; import javax.ejb.ActivationConfigProperty; import javax.ejb.MessageDriven; import javax.ejb.MessageDrivenContext; import javax.ejb.TransactionAttribute; import javax.ejb.TransactionAttributeType; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageListener; import javax.jms.TextMessage; import org.apache.log4j.Logger; @MessageDriven(activationConfig = { @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"), @ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/MDBDemo") }) public class Receiver implements MessageListener { private int count = 0; private static final int MODULUS = 100; private static final Logger log = Logger.getLogger(Receiver.class); @Resource private MessageDrivenContext context; @TransactionAttribute(TransactionAttributeType.REQUIRED) public void onMessage(Message message) { log.info("Recieve " + count + " of " + MODULUS); boolean accept = count == 0; count = (count + 1) % MODULUS; if (accept) try { log.info("Accepted message: " + ((TextMessage) message).getText()); } catch (JMSException e) { log.error("JMX Exception", e); context.setRollbackOnly(); } else { log.info("Rejecting message."); context.setRollbackOnly(); } } }
There are no deployment descriptors in the ejb-jar file (neither ejb-jar.xml nor jboss.xml).
There is no MBean descriptor for the queue/MDBDemo Queue.
The message-driven-bean invoker proxy binding in standardjboss.xml has been edited to have MaxTimesRedelivered = 3 instead of the default of 10; this does not appear to have any effect on how many times MDB delivery is attempted before JBoss gives up and sends the message to the DLQ. (Related question: will removing the DLQConfig element entirely accomplish what I want?)
All of this is running under JBoss 4.0.4.GA.