MainframeCICSCICS Complete Reference

CICS Transient Data Queues: WRITEQ TD, READQ TD, DELETEQ TD — Complete Guide

TT
TopicTrick Team
CICS Transient Data Queues: WRITEQ TD, READQ TD, DELETEQ TD — Complete Guide

Introduction: Transient Data Queues in CICS

While Temporary Storage (TS) queues provide random-access, re-readable storage for session state and browse buffers, Transient Data (TD) queues serve a different purpose: sequential, one-way message delivery. Like a mailbox or a print spool, items written to a TD queue are read in order, and once read they are gone. This makes TD queues the ideal mechanism for logging, printing, inter-task messaging, and triggering batch processing from online transactions.

CICS supports two types of TD queues: intrapartition queues (stored within the CICS region, supports ATI) and extrapartition queues (backed by a z/OS sequential dataset, readable by external batch jobs). Both use the same WRITEQ TD and READQ TD commands.


EXEC CICS WRITEQ TD: Writing to a Transient Data Queue

WRITEQ TD writes one record to the end of a named TD queue. Unlike WRITEQ TS, there are no item numbers — items are always appended sequentially:

cobol
WORKING-STORAGE SECTION.
01  WS-LOG-RECORD.
    05  WS-LOG-DATE    PIC X(10).
    05  WS-LOG-TIME    PIC X(08).
    05  WS-LOG-TRNID   PIC X(4).
    05  WS-LOG-TRMID   PIC X(4).
    05  WS-LOG-TYPE    PIC X(1).    *> E=Error, I=Info, W=Warning
    05  WS-LOG-MSG     PIC X(60).
01  WS-LOG-LEN         PIC S9(4) COMP.
01  WS-RESP            PIC S9(8) COMP VALUE ZERO.

WRITE-TO-ERROR-LOG.
    EXEC CICS ASKTIME ABSTIME(WS-ABSTIME) END-EXEC
    EXEC CICS FORMATTIME ABSTIME(WS-ABSTIME)
              DDMMYYYY(WS-LOG-DATE) DATESEP('/')
              TIME(WS-LOG-TIME) TIMESEP(':')
    END-EXEC
    MOVE EIBTRNID  TO WS-LOG-TRNID
    MOVE EIBTRMID  TO WS-LOG-TRMID
    MOVE 'E'       TO WS-LOG-TYPE
    MOVE WS-ERR-MSG TO WS-LOG-MSG
    MOVE LENGTH OF WS-LOG-RECORD TO WS-LOG-LEN

    EXEC CICS WRITEQ TD
              QUEUE('CSERR')
              FROM(WS-LOG-RECORD)
              LENGTH(WS-LOG-LEN)
              RESP(WS-RESP)
    END-EXEC

    IF WS-RESP NOT = DFHRESP(NORMAL)
        *> Can't even write to the log queue — write to TS instead
        PERFORM EMERGENCY-LOG-TO-TS
    END-IF.

Well-known IBM-supplied TD queue names:

QueuePurpose
CSSLCICS system log — general system messages
CSMTCICS master terminal output
CSDLCICS statistics and monitoring data
CSCSCICS security violation log
CSERCICS error messages

Custom application TD queues (like CSERR in the example above) must be defined as TDQUEUE resources in the CICS CSD.


EXEC CICS READQ TD: Reading from a Transient Data Queue

READQ TD reads the next record from the front of the queue. The record is removed after reading (destructive read):

cobol
WORKING-STORAGE SECTION.
01  WS-QUEUE-NAME  PIC X(4) VALUE 'PRNT'.
01  WS-PRINT-REC   PIC X(133).
01  WS-PRINT-LEN   PIC S9(4) COMP VALUE +133.

PROCEDURE DIVISION.
PROCESS-PRINT-QUEUE.
    PERFORM UNTIL WS-EOF
        EXEC CICS READQ TD
                  QUEUE(WS-QUEUE-NAME)
                  INTO(WS-PRINT-REC)
                  LENGTH(WS-PRINT-LEN)
                  RESP(WS-RESP)
        END-EXEC

        EVALUATE WS-RESP
            WHEN DFHRESP(NORMAL)
                PERFORM FORMAT-AND-PRINT-LINE
            WHEN DFHRESP(QZERO)
                *> Queue is empty — no more items
                MOVE 'Y' TO WS-EOF-FLAG
            WHEN DFHRESP(QIDERR)
                *> Queue does not exist
                MOVE 'Y' TO WS-EOF-FLAG
                MOVE 'PRINT QUEUE NOT FOUND.' TO WS-ERR-MSG
            WHEN OTHER
                PERFORM HANDLE-READQ-ERROR
                MOVE 'Y' TO WS-EOF-FLAG
        END-EVALUATE
    END-PERFORM.

Critical difference from TS queues: when READQ TD returns DFHRESP(QZERO), the queue exists but is empty. DFHRESP(QIDERR) means the queue name itself is not defined. Both indicate there is nothing to read, but they have different implications for error handling.


EXEC CICS DELETEQ TD: Deleting a TD Queue

For intrapartition queues, DELETEQ TD empties the queue (removes all unread items). Note this differs slightly from TS — TD queues themselves remain defined (they are system resources); only the content is removed:

cobol
EXEC CICS DELETEQ TD
          QUEUE(WS-QUEUE-NAME)
          RESP(WS-RESP)
END-EXEC.

Automatic Transaction Initiation (ATI)

ATI is the most powerful feature of intrapartition TD queues. When the queue item count reaches a defined trigger level, CICS automatically starts a predefined transaction — without any human or program intervention.

CSD Definition for ATI

The TDQUEUE resource definition in the CSD includes:

text
CEDA DEFINE TDQUEUE(PRNT)
     GROUP(MYAPP)
     TYPE(INTRAPARTITION)
     TRIGGERLEVEL(50)        /* Start ATI when queue has 50 items */
     TRANSID(PRTX)           /* Start transaction PRTX            */
     FACILITYNAME(L001)      /* Use this terminal for the transaction */
     RECOVSTATUS(NO)

When 50 items accumulate in queue PRNT, CICS automatically starts transaction PRTX, which drains the queue.

The ATI-Triggered Processing Program

cobol
IDENTIFICATION DIVISION.
PROGRAM-ID. PRTXPGM.

*── This program is started by ATI when queue PRNT reaches trigger ──

DATA DIVISION.
WORKING-STORAGE SECTION.
01  WS-QUEUE-NAME  PIC X(4) VALUE 'PRNT'.
01  WS-PRINT-LINE  PIC X(133).
01  WS-PRINT-LEN   PIC S9(4) COMP VALUE +133.
01  WS-RESP        PIC S9(8) COMP VALUE ZERO.
01  WS-EOF         PIC X VALUE 'N'.
01  WS-COUNT       PIC 9(6) VALUE ZERO.

PROCEDURE DIVISION.
MAIN-LOGIC.
    PERFORM UNTIL WS-EOF = 'Y'
        EXEC CICS READQ TD
                  QUEUE(WS-QUEUE-NAME)
                  INTO(WS-PRINT-LINE)
                  LENGTH(WS-PRINT-LEN)
                  RESP(WS-RESP)
        END-EXEC

        EVALUATE WS-RESP
            WHEN DFHRESP(NORMAL)
                ADD 1 TO WS-COUNT
                PERFORM WRITE-TO-PRINTER
            WHEN DFHRESP(QZERO)
                MOVE 'Y' TO WS-EOF
            WHEN OTHER
                PERFORM HANDLE-ERROR
                MOVE 'Y' TO WS-EOF
        END-EVALUATE
    END-PERFORM

    EXEC CICS RETURN END-EXEC.

WRITE-TO-PRINTER.
    *── Write to a CICS-attached printer or extrapartition queue ──
    EXEC CICS WRITEQ TD
              QUEUE('PRTR')
              FROM(WS-PRINT-LINE)
              LENGTH(WS-PRINT-LEN)
    END-EXEC.

ATI Trigger Level Considerations

The trigger level controls the balance between responsiveness and efficiency:

  • Trigger level = 1: ATI starts a task for every item written. Maximum responsiveness but high overhead from frequent task starts.
  • Trigger level = 50: Batch 50 items before triggering. Higher throughput, slightly delayed processing.
  • Trigger level = 0: ATI disabled — the queue must be drained manually or by a scheduled transaction.

Extrapartition TD Queues: Connecting CICS to Batch

An extrapartition TD queue is backed by a sequential z/OS dataset. Writing to it from CICS creates records in the file that a subsequent batch job can process. This is the classic pattern for CICS-triggered batch reporting:

CSD Definition

text
CEDA DEFINE TDQUEUE(RPTE)
     GROUP(MYAPP)
     TYPE(EXTRAPARTITION)
     DDNAME(RPTFILE)         /* DD name in CICS JCL */
     DISPOSITION(MOD)        /* Append to file */
     OPENTIME(INITIAL)       /* Open when CICS starts */

The RPTFILE DD in the CICS region's JCL points to the sequential dataset.

Writing to an Extrapartition Queue

cobol
*── Write a formatted report line to the output file ─────────────
WRITE-REPORT-LINE.
    MOVE WS-FORMATTED-LINE TO WS-RPT-RECORD
    MOVE LENGTH OF WS-RPT-RECORD TO WS-RPT-LEN

    EXEC CICS WRITEQ TD
              QUEUE('RPTE')
              FROM(WS-RPT-RECORD)
              LENGTH(WS-RPT-LEN)
              RESP(WS-RESP)
    END-EXEC.

After CICS closes the extrapartition queue (at CICS shutdown or explicit close), the sequential file can be processed by a batch job for further formatting, sorting, or printing via JES.


Common TD Queue Mistakes

Mistake 1: Using READQ TD on an extrapartition queue opened for OUTPUT. Extrapartition queues defined with DISPOSITION(MOD) or OUTPUT are write-only from CICS. Attempting READQ TD returns INVREQ.

Mistake 2: Expecting READQ TD to be non-destructive. Unlike READQ TS, reading a TD queue item removes it permanently. There is no way to re-read a TD queue item after it has been read. If you need re-readable queues, use TS.

Mistake 3: Not handling QZERO on READQ TD in ATI programs. The ATI program starts when the queue reaches the trigger level, but by the time it runs, another ATI start may have already drained some items. Always handle QZERO gracefully — it means the queue is empty now, which is normal.

Mistake 4: Writing very long records to extrapartition queues. Extrapartition queues are backed by sequential QSAM files. The maximum record length is defined by the BLKSIZE and LRECL of the backing DD. Writing a record longer than LRECL causes LENGERR.


Key Takeaways

CICS Transient Data queues are the standard mechanism for sequential message delivery, logging, print spooling, and ATI-triggered batch initiation from online transactions. Intrapartition queues live within CICS and support ATI (the killer feature that allows online transactions to trigger batch processing automatically). Extrapartition queues connect CICS to z/OS batch by writing to sequential files. The core discipline is remembering that TD queue reads are destructive — unlike TS, there is no going back to re-read an item.

For understanding how CICS schedules time-based transaction starts and manages task delays, continue with CICS Interval Control. For the complete CICS course, visit the CICS Mastery Course.