1 Reply Latest reply on Jan 13, 2007 9:13 AM by timfox

    AUTO_ACKNOWLEDGE weirdness

    timfox

      Something struck me as a bit strange with the AUTO_ACKNOWLEDGE and MessageListeners as defined in the JMS spec.

      It has always been my understanding that using AUTO_ACKNOWLEDGE gives a "at most once" delivery guarantee.

      You get a "at most once" guarantee because (with receive() at least) the message is acknowledged *before* the call to receive() has returned, so if failure occurs between acking and giving you the message it is effectively lost you - you didn't receive it, but you could never get it more than once.

      However when using a MessageListener breaks this breaks down. For a MessageListener, according to the JMS spec, if you are using AUTO_ACKNOWLEDGE then the message should be acked *after* the onMessage has finished executing.

      This means if a failure occurs right at the end of the onMessage but before the message is acked, it could be received again - i.e. you could get duplicates, and the "at most once" delivery guarantee is lost.

      In order to maintain "at most once" semantics the message should be acked before onMessage is called.

      Is this just a stupidity in the JMS spec or can you think of any reason it was done this way?

        • 1. Re: AUTO_ACKNOWLEDGE weirdness
          timfox

          It gets even more confusing :)

          For an MDB, using JMSContainerInvoker (I'm not sure if JCA 1.5 inflow shows the same behaviour) and with ack mode AUTO_ACKNOWLEDGE, the message is received by the connection consumer before handing off to to the MDB, therefore for an MDB and AUTO_ACKNOWLEDGE the message is acked *before* the MDB onMessage is executed, which is the opposite of what happens for a standard non MDB MessageListener.

          Nice.

          The more I delve into the MDB container, JCA 1.5 inflow, and JMS message delivery, the more I realise how full of contradictions, badly specced/unspecced areas and inconsistent behaviour this area is. :)