ibm-messaging / mq-golang

Calling IBM MQ from Go applications
Apache License 2.0
168 stars 60 forks source link

Question: Acking Messages #81

Closed sasbury closed 5 years ago

sasbury commented 5 years ago

I am using v3.3.4 of the library, but am new to MQ-series. I am curious how to manually ack messages from a queue.

It looks like I do MQGMO_SYNCPOINT on the get options, and then use Back or Cmit on the queue manager to ack/nack. If this is true, then I think I need to have a separate queue manager for each queue that I am processing in a go routine. I am concerned about having too many connections.

The JMS versions of the library seem to have ack on the message itself, so I want to confirm I am using the library correctly.

ibmmqmet commented 5 years ago

MQ does not really have the same concept as JMS's acknowledgement. Everything to do with reliable delivery is expressed in terms of transactions.

JMS has both ack and transaction ideas, but the distinction is a bit blurry, especially in different concrete implementations of the JMS API.

With MQ, to ensure a message has been correctly delivered and will not be redelivered or lost, then you would usually use the MQGMO_SYNCPOINT (or MQGMO_SYNCPOINT_IF_PERSISTENT, as the reliability is less important with non-persistent messages and you may not know in advance what you've been sent) option along with a following MQCMIT/MQBACK at some appropriate time. Perhaps that is after every individual message; perhaps it is after a batch have been received from the same or multiple queues. Often a transaction will cover both the MQGET of a message and the MQPUT of a reply. But that's an application design choice based on knowing the logic of how operations need to be grouped. The MQCMIT will commit operations on all queues for the connection that have been affected by a GET/PUT since the last commit. There's not usually any need to have multiple connections with each "owning" a single queue - there's usually some relationship between the queues in use that the application is built for.

Most applications use the MQI synchronously so at every point they know which queues they are getting from or putting to; they know whether it's an appropriate time to commit. Using an asynchronous message listener (MQCB/MQCTL) makes it a little more complex as you don't know in advance which queue will be delivering messages if you are potentially retrieving from multiple, but that again is a standard part of application design. And you can still do MQCMIT from within a callback listener. See https://www.ibm.com/support/knowledgecenter/en/SSFKSJ_9.1.0/com.ibm.mq.ref.dev.doc/q101730_.htm for considerations on callback listeners. And then there's the MQCTLO_THREAD_AFFINITY option in MQCTL that gives more control of the listener invocation ... But that's probably getting too deep now.

sasbury commented 5 years ago

Thanks ibmmqmet :-)