Search code examples
javajmsmessagingamqpmessagebroker

How guaranteed delivery works in JMS client acknowledgment mode?


In jms (v1.0) subscriber client ack mode, message.acknowledge() is the only way to send an ack back to server(broker) side. The actual behaviour is if client ack to message3 then message sender(broker) client acks to all messages up to message3[1].

i.e msg1, msg2, msg3 is delivered to the client in order.

  1. Client process messages ACK for every message, msg1, msg2 and msg3. >> OK
  2. Knowing the actual behaviour client acks as batches(batch size=3), so asks to msg3 > OK (all messages upto msg3 get acked)

In scenario 1 and 2, broker get notified that client ACK to all 3 messages delivered. And client also actually process all 3 and ACK back.

Consider following scenario :

a. msg1 comes to client.

b. failed to process msg1. So avoid ack back. (msg1 never processed or acked from client side)

c. msg2 comes and successfully processed. And ack to msg2.

Therefore in the above scenario client ack does not guarantee the delivery of msg1.

Please explain is there a workaround to guaranteed delivery when batch process with client ack through JMS 1.0 spec.

[1] http://docs.oracle.com/javaee/7/api/javax/jms/Message.html#acknowledge


Solution

  • According to the spec:

    By invoking acknowledge on a consumed message, a client acknowledges all messages consumed by the session that the message was delivered to.

    So, the deal is to not acknowledge any more messages in a session where a message has failed.

    Instead, if you detect a failure, you could either:

    1. Tear down the session (or even Connection).

    2. Invoke recover on your Session. That will restart message delivery with the oldest unacknowledged message.