MQ

 View Only
  • 1.  CurrentQDepth Question

    Posted Tue June 07, 2022 02:03 PM
    I have a design that will use a CICS transaction and a batch job (this is on z/OS). 

    The current design uses the CICS transaction to Get and process the MQ messages. However, the volume of messages, and more importantly, the amount of DB2 processing I need to do with each MQ message is such that I would like to re-write the processing in a batch program, and use the CICS program to monitor / trigger the batch program. 

    Here is the high-level design I am thinking about:

    Set queue triggering on the FILL queue to trigger my CICS transaction every time a message arrives on the queue. When the CICS transaction is triggered., one of two things will be true. Either:

    1. Queue Depth > 1. In this case, a message arrived on the queue, but the prior one(s) are still being processed. This means the batch job that processes the FILL queue is running, and the CICS transaction should terminate.
    2. Queue Depth = 1. In this case, a message arrived on the queue, and any prior messages have been processed. This means the batch job that processes the FILL queue is NOT running. In this case the CICS transaction DEMANDS in the batch job, then terminates.

    Note that the CICS transaction never reads messages from the queue (If the transaction is triggered, we know there is a message on the queue. The CICS transaction never processes message, so it does not do an MQ GET or MQ INQUIRE; just by being triggered, we know there is a message on the queue).

    That CICS transaction DEMANDs in a batch job that will read and process the FILL queue until it is empty (with a few second WaitInterval during the MQ GET, such that if a message is soon to arrive, it will wait, vs. the system overhead of terminating the batch program, and having to re-start it just a few seconds later).

    The batch program will process one MQ message at a time, then COMMIT. It will then GET the next message, etc, and will continue processing until the FILL queue is empty, i.e. it was 'triggered' by the occurrence of 1 FILL queue message, but once the batch job starts, it will continue processing the queue until the queue is empty.

    The above depends on the CICS transaction using an MQINQ (inquire) on the queue depth attribute (CurrentQDepth) to know if it should trigger the batch job or not.

    Here is what IBM says about CurrentQDepth:

    "It is incremented during an MQPUT call, and during backout of an MQGET call. It is decremented during a nonbrowse MQGET call, and during backout of an MQPUT call. The effect of this is that the count includes messages that have been put on the queue within a unit of work, but that have not yet been committed, even though they are not eligible to be retrieved by the MQGET call. Similarly, it excludes messages that have been retrieved within a unit of work using the MQGET call, but that have yet to be committed."

    I think what this means for my design is the following:

    • My CICS transaction and batch job are different units of work
    • As a result, an MQINQ on CurrentQDepth issued from the CICS program:
      • will include the message being processed by the batch job until the batch program COMMITs the MQ
      • will not include the message being processed by the batch job after batch program COMMITs the MQ

    Does that all seem feasible, or am I doing this the hard way?



    ------------------------------
    Curt Gilker
    ------------------------------


  • 2.  RE: CurrentQDepth Question

    Posted Tue June 07, 2022 03:46 PM
    MQ triggering rules do this for you. Trigger first will only generate a trigger message if the queue is not already being processed, based on whether the queue is open for input. A trigger message is also generated if the processing application closes the queue and it is not empty, to avoid a race condition.

    See here: https://www.ibm.com/docs/en/ibm-mq/9.2?topic=queuing-starting-mq-applications-using-triggers for a triggering overview, and here: https://www.ibm.com/docs/en/ibm-mq/9.2?topic=triggers-conditions-trigger-event for the triggering rules.

    ------------------------------
    Rich Harran
    ------------------------------



  • 3.  RE: CurrentQDepth Question

    IBM Champion
    Posted Wed June 08, 2022 04:14 PM
    I'm on my phone so this will be shorter than normal.

    Another approach is to trigger a cics transaction

    Cics transaction does mqget. Db2 update commit. Loop
    Get next message. If q empty then exit.
    Loop for max of n times.(eg 10 to 100)
    Inq qdepth, number if handles.
    If queudepth gt x and number if handles Lt y then start 2 instances of transaction and end.

    This will grow number of concurrent transaction instances up to a limit y per queue manager.

    It allows cics to start the transaction on the optimum cics and lpar, so work can move around the sysplex.

    If you shut down a cics it Will continue to work.

    You might consider a queue a_to_m for records with data key in range a to m and another queue for n to z. You can then limit where transactions to run and so one cics does records atom and another does n to z, and do reduce db2 contention.

    This does not involve batch.

    Colin ( on his hols)