pavloN
pavloN

Reputation: 73

IBM MQ How read one by one message, not all available in a queue manager at once?

Now, my app receives all available messages in a Queue manager. I collect them locally and process one by one. Could do I configure it to receive one message, do some work (it can take some time), delete the received message, repeat? Is this behavior possible with IBM MQ? The code was updated

function listenToMQ() {
      const qMgr = inbound.queueManagerName;
      const qName = inbound.queueName;
      const connName = inbound.host;

      const cno = new mq.MQCNO();
      const sco = new mq.MQSCO();
      const csp = new mq.MQCSP();
      const cd = new mq.MQCD();
      cno.SecurityParms = csp;
      csp.UserId = inbound.userID;
      csp.authenticationType = 0;
      cno.Options |= MQC.MQCNO_CLIENT_BINDING;
      cd.ConnectionName = connName;
      cd.ChannelName = inbound.channelName;
      cd.SSLClientAuth = MQC.MQSCA_OPTIONAL;
      cd.MaxMsgLength = 104857600;
      cno.ClientConn = cd;
      cno.SSLConfig = sco;

      mq.setTuningParameters({
        syncMQICompat: true   });

      mq.Connx(qMgr, cno, function(err, hConn) {
        if (err) {
          logger.errorLogger().error(err.message);
        } else {
          const od = new mq.MQOD();
          od.ObjectName = qName;
          od.ObjectType = MQC.MQOT_Q;
          const openOptions = MQC.MQOO_BROWSE;
          mq.Open(hConn, od, openOptions, function(err, hObj) {
            queueHandle = hObj;
            if (err) {
              logger.errorLogger().error(err.message);
            } else {
              getMessages();
            }
          });
        }   }); }


    function getMessages() {
      const md = new mq.MQMD();
      const gmo = new mq.MQGMO();

      gmo.Options =
        MQC.MQGMO_NO_SYNCPOINT |
        MQC.MQGMO_MQWI_UNLIMITED |
        MQC.MQGMO_CONVERT |
        MQC.MQGMO_FAIL_IF_QUIESCING;
      gmo.Options |= MQC.MQGMO_BROWSE_FIRST;

      gmo.MatchOptions = MQC.MQMO_NONE;

      mq.setTuningParameters({
        getLoopPollTimeMs: 500   });   mq.Get(queueHandle, md, gmo, getCB); }



      function getCB(err, hObj, gmo, md, buf, hConn) {
        if (md.Format == "MQSTR") {
          console.log(md);
          const message = decoder.write(buf);
          updateDB(getMetaFeed(message));
        } 
        mq.Cmit(hConn);
      }

            gmo.Options &= ~MQC.MQGMO_BROWSE_FIRST;
            gmo.Options |= MQC.MQGMO_BROWSE_NEXT;   } 

Upvotes: 0

Views: 1216

Answers (1)

Morag Hughson
Morag Hughson

Reputation: 7525

Yes, most certainly you can.

Your application can get one message, perhaps using syncpoint if it is a message that drives some work that needs done, do the work and then when the work is done commit the get of the message and then go and get the next one. If the work that needs to be done is also transactional (e.g. update a database), then a global transaction could be used to commit both the MQ message and the update of the other transactional resource at the same time.

The code you show in your question appears to be doing a browse of messages (queue opened with MQOO_BROWSE and then messages read using MQGMO_BROWSE_FIRST and then MQGMO_BROWSE_NEXT). I'm not sure how or when your application currently removes the messages from the queue?

Your current code appears to be processing the messages one by one already, so the only changes needed would be to the get options (and to add a commit call).

Upvotes: 1

Related Questions