Can't you set up the queue so it only attempts to deliver it once.
In JBoss Messaging it would be something like:
<mbean code="org.jboss.jms.server.destination.QueueService" name="jboss.messaging.destination:service=Queue,name=SomeQueue" xmbean-dd="xmdesc/Queue-xmbean.xml"> <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends> <depends>jboss.messaging:service=PostOffice</depends> <attribute name="MaxDeliveryAttempts">1</attribute> </mbean>
If the delivery isn't successful, the message will end up in the dead letter queue.
Hope it helps ;)
Yes, that's currently the exact configuration of my queue. There are two things I would like to solve:
1.) The processing in my MDB can take a long time. During this time, the provider is holding the unacknowledged message. This probably isn't a big deal, but in my case it doesn't have to, so if there is anything I can do to alleviate that behavior, I would like to do it.
2.) This is the bigger issue, because it is the exact opposite of what I need to happen, and kind of unexpected. In my test, I put a sleep statement in my MDB to simulate long processing. I send five messages to the queue, so five MDB instances start and go to sleep. At that point I crash the server. When the server starts back up, those messages get delivered again (and the MDBs go back to sleep). If that had been my actual application logic, it would be duplicating events, which would be bad.
If this is the behavior, I'll have to check for duplicates anyway, and might as well use Dups-ok-acknowledge.
One thing I didn't check, which I will check tomorrow, is if the redelivered flag is set the second time around. Since I have MaxDeliveryAttempts set to 1, I would have expected it to go to the DLQ in that case.
Ok, I checked and JMSRedelivered is set to false.
After pouring over the specs, I think I've corrected some of my misunderstandings.
According to the JMS spec, with AUTO_ACKNOWLEDGE, the acknowledgment occurs after receive or onMessage. Since the MDB is using the MessageListener interface, I would assume the receipt must happen after onMessage. I guess what I'm really after is CLIENT_ACKNOWLEDGE, which the EJB spec does not support. (Unfortunate, because I'll just have to waste time doing all the JMS and thread pool programming to simulate an EJB container with this functionality. That, or do duplicate checking)
All that said, I still think there is a bug with AUTO_ACKNOWLEDGE. The JMS spec states that the client should be prepared for re-delivery of the last consumed message, for this very reason. (Processing occurring in onMessage, and JMS crashing before receipt). It states that in this situation, JMSRedelivered should be set to true. (Which it is not in my example). I'll have to do more testing, and take my questions to the JMS forum.