20 min read

> No GnuCOBOL equivalent exists for CICS programming. CICS (Customer Information Control System) is an IBM proprietary transaction processing system that runs exclusively on z/OS. All examples in this chapter require IBM Enterprise COBOL with CICS...

Chapter 25: Advanced CICS Programming

[IBM Enterprise COBOL]

No GnuCOBOL equivalent exists for CICS programming. CICS (Customer Information Control System) is an IBM proprietary transaction processing system that runs exclusively on z/OS. All examples in this chapter require IBM Enterprise COBOL with CICS Transaction Server.


Introduction

In Chapter 24 we introduced the fundamentals of CICS programming: basic pseudo-conversational design, simple BMS maps, and elementary CICS API commands. In this chapter we advance into the patterns and techniques that production CICS applications actually demand. We will build multi-screen applications with complex navigation flows, integrate CICS with DB2 databases, manage queues for inter-transaction communication, implement robust security and error handling, and expose legacy CICS transactions as modern web services.

The techniques in this chapter represent decades of accumulated best practices from enterprises that process millions of transactions per day. While the CICS API has evolved significantly since its introduction in 1969, the core principles of efficient transaction processing remain remarkably consistent. Understanding these advanced patterns is essential for any COBOL programmer working in a mainframe environment.


25.1 Advanced Pseudo-Conversational Design Patterns

Review of the Pseudo-Conversational Model

Recall that CICS applications must use pseudo-conversational design to avoid holding resources while waiting for user input. The program sends a map to the terminal, issues EXEC CICS RETURN TRANSID(xxxx), and terminates. When the user presses a key, CICS starts a new task with the same transaction ID, and the program must reconstruct its context.

The State Machine Pattern

Production CICS applications manage complex workflows by treating the application as a finite state machine. The current state is stored in the COMMAREA and determines how the program processes each interaction.

       01  WS-COMM-AREA.
           05  CA-STATE              PIC X(02).
               88  ST-INITIAL       VALUE '00'.
               88  ST-MENU          VALUE '10'.
               88  ST-DETAIL        VALUE '20'.
               88  ST-CONFIRM       VALUE '30'.
               88  ST-COMPLETE      VALUE '40'.
           05  CA-PREV-STATE         PIC X(02).
           05  CA-ACCOUNT-NUM        PIC X(10).
           05  CA-ACTION-CODE        PIC X(01).
               88  AC-INQUIRY       VALUE 'I'.
               88  AC-UPDATE        VALUE 'U'.
               88  AC-DELETE        VALUE 'D'.

The main procedure becomes a dispatcher that routes control based on state:

           EVALUATE TRUE
               WHEN ST-INITIAL
                   PERFORM 1000-FIRST-TIME
               WHEN ST-MENU
                   PERFORM 2000-PROCESS-MENU
               WHEN ST-DETAIL
                   PERFORM 3000-PROCESS-DETAIL
               WHEN ST-CONFIRM
                   PERFORM 4000-PROCESS-CONFIRM
               WHEN OTHER
                   PERFORM 9000-STATE-ERROR
           END-EVALUATE.

Complex applications need backward navigation. Store a navigation stack in the COMMAREA:

       01  CA-NAV-STACK.
           05  CA-NAV-DEPTH          PIC 9(02) VALUE 0.
           05  CA-NAV-ENTRY OCCURS 10 TIMES.
               10  CA-NAV-STATE      PIC X(02).
               10  CA-NAV-KEY        PIC X(20).

When navigating forward, push the current state. When the user presses PF3 (typically mapped to "back"), pop the previous state and return to it. This pattern supports arbitrary depth of navigation while keeping the COMMAREA compact.

Session Timeout Handling

Production applications must handle the case where a user's session has been idle for too long:

           EXEC CICS ASKTIME
               ABSTIME(WS-CURRENT-TIME)
           END-EXEC.

           COMPUTE WS-ELAPSED =
               WS-CURRENT-TIME - CA-LAST-ACTIVITY.

           IF WS-ELAPSED > WS-TIMEOUT-LIMIT
               PERFORM 9100-SESSION-TIMEOUT
           ELSE
               MOVE WS-CURRENT-TIME TO CA-LAST-ACTIVITY
           END-IF.

25.2 Multi-Screen Applications: Managing Flow Between Maps

The Multi-Map Architecture

Real CICS applications rarely consist of a single screen. A typical application might involve a menu screen, a list screen, a detail screen, an edit screen, and a confirmation screen. Each screen has its own BMS mapset, and the program must manage transitions between them.

[IBM Enterprise COBOL] BMS (Basic Mapping Support) mapsets are defined in separate assembler-like source files and compiled by the CICS translator to generate both physical maps (load modules) and symbolic maps (COBOL copybooks).

Example: Menu-Detail-Confirmation Flow

Consider an application where: 1. The user sees a menu and selects an option 2. The detail screen shows account information 3. After changes, a confirmation screen appears 4. Upon confirmation, the transaction completes

Each mapset is defined in a separate BMS source file. The menu mapset (see example-01-menu-map.bms) defines fields for option selection. The detail mapset (see example-01-detail-map.bms) defines fields for data display and editing.

The COBOL program (see example-01-multi-map.cob) manages the complete flow:

       PROCEDURE DIVISION.
           IF EIBCALEN = ZERO
               PERFORM 1000-FIRST-TIME
           ELSE
               MOVE DFHCOMMAREA TO WS-COMMAREA
               EVALUATE CA-CURRENT-MAP
                   WHEN 'MENU'
                       PERFORM 2000-PROCESS-MENU
                   WHEN 'DETAIL'
                       PERFORM 3000-PROCESS-DETAIL
                   WHEN 'CONFIRM'
                       PERFORM 4000-PROCESS-CONFIRM
               END-EVALUATE
           END-IF.

Map Management Best Practices

  1. Clear the map before sending: Always initialize the symbolic map to LOW-VALUES before populating it. This ensures that only fields you explicitly set are transmitted, reducing network traffic on 3270 connections.

  2. Use MAPONLY vs DATAONLY appropriately: Send MAPONLY when only the static portions of the screen need updating. Send DATAONLY when only the data fields change. Send both map and data for the first display.

  3. Attribute byte manipulation: Control field attributes programmatically using the attribute byte to highlight errors, protect fields, or control cursor position:

           IF WS-AMOUNT-ERROR
               MOVE DFHBMFSE TO AMOUNTA
                   OF DETAIL-MAPO
               MOVE 'Invalid amount' TO AMOUNTM
                   OF DETAIL-MAPO
           END-IF.

Screen Painting and Cursor Positioning

Use the CURSOR option on SEND MAP to position the cursor at the first error field:

           EXEC CICS SEND
               MAP('DETAILM')
               MAPSET('DETAILP')
               FROM(DETAIL-MAPO)
               DATAONLY
               CURSOR(WS-CURSOR-POS)
               ERASE
           END-EXEC.

Calculate cursor position based on the field that has the first error. Each 3270 screen position is calculated as (row - 1) * 80 + column.


25.3 COMMAREA Design for Complex Applications

COMMAREA Fundamentals Revisited

The COMMAREA (Communication Area) is the primary mechanism for passing data between pseudo-conversational interactions and between linked programs. Understanding its design is critical for maintainable applications.

[IBM Enterprise COBOL] The COMMAREA has a maximum size of 32,763 bytes. For larger data requirements, use channels and containers (discussed in Section 25.4).

Versioning Strategy

As applications evolve, the COMMAREA structure changes. A versioning strategy prevents problems when multiple versions of a program are active during migration:

       01  WS-COMMAREA.
           05  CA-VERSION            PIC 9(04) VALUE 3.
           05  CA-EYE-CATCHER       PIC X(08) VALUE 'MYAPPCA '.
           05  CA-LENGTH             PIC S9(04) COMP VALUE 0.
      *    --- Version 1 fields (original) ---
           05  CA-V1-DATA.
               10  CA-TRANS-STATE    PIC X(02).
               10  CA-USER-ID       PIC X(08).
               10  CA-ACCOUNT-NUM   PIC X(10).
      *    --- Version 2 additions ---
           05  CA-V2-DATA.
               10  CA-BRANCH-CODE   PIC X(04).
               10  CA-ACCESS-LEVEL  PIC 9(01).
      *    --- Version 3 additions ---
           05  CA-V3-DATA.
               10  CA-SESSION-TOKEN PIC X(32).
               10  CA-LAST-ACTIVE   PIC S9(15) COMP-3.

On entry, check the version and handle appropriately:

           EVALUATE CA-VERSION
               WHEN 1
                   INITIALIZE CA-V2-DATA
                   INITIALIZE CA-V3-DATA
                   MOVE 3 TO CA-VERSION
               WHEN 2
                   INITIALIZE CA-V3-DATA
                   MOVE 3 TO CA-VERSION
               WHEN 3
                   CONTINUE
               WHEN OTHER
                   PERFORM 9200-VERSION-MISMATCH
           END-EVALUATE.

Expansion Strategy

Design COMMREAs with expansion in mind:

  1. Reserve filler space: Always include filler at the end of the COMMAREA for future fields.
  2. Use a length field: Include the actual data length so programs can detect truncation.
  3. Pack data efficiently: Use COMP and COMP-3 fields where appropriate to conserve space.
  4. Separate static and dynamic sections: Place infrequently changing data (user profile) before frequently changing data (transaction state).
       01  WS-COMMAREA.
           05  CA-HEADER.
               10  CA-VERSION        PIC 9(04).
               10  CA-LENGTH         PIC S9(04) COMP.
               10  CA-EYE-CATCHER   PIC X(08).
           05  CA-STATIC-DATA.
               10  CA-USER-PROFILE  PIC X(100).
           05  CA-DYNAMIC-DATA.
               10  CA-SCREEN-DATA   PIC X(500).
           05  CA-FILLER            PIC X(200).

25.4 CICS Channels and Containers

The Modern Alternative to COMMAREA

[IBM Enterprise COBOL] CICS TS V3.1 introduced channels and containers as a modern replacement for COMMAREA. Unlike COMMAREA, channels have no practical size limit and support structured, named data areas.

Concepts

A channel is a named collection of containers. A container is a named data area within a channel. When you LINK or XCTL to a program, you can pass a channel instead of (or in addition to) a COMMAREA.

Creating and Using Containers

      * Put data into a container
           EXEC CICS PUT CONTAINER('CUST-DATA')
               FROM(WS-CUSTOMER-RECORD)
               FLENGTH(LENGTH OF WS-CUSTOMER-RECORD)
               CHANNEL('INQUIRY-CHAN')
           END-EXEC.

      * Link to program with the channel
           EXEC CICS LINK PROGRAM('CUSTINQ')
               CHANNEL('INQUIRY-CHAN')
           END-EXEC.

      * Get response data from a container
           EXEC CICS GET CONTAINER('CUST-RESP')
               CHANNEL('INQUIRY-CHAN')
               INTO(WS-RESPONSE-DATA)
               FLENGTH(WS-RESP-LENGTH)
           END-EXEC.

In the Called Program

The called program retrieves the channel name and reads containers:

           EXEC CICS ASSIGN CHANNEL(WS-CHANNEL-NAME)
           END-EXEC.

           IF WS-CHANNEL-NAME NOT = SPACES
               EXEC CICS GET CONTAINER('CUST-DATA')
                   CHANNEL(WS-CHANNEL-NAME)
                   INTO(WS-CUSTOMER-RECORD)
                   FLENGTH(WS-DATA-LENGTH)
               END-EXEC
           END-IF.

Advantages Over COMMAREA

Feature COMMAREA Channels/Containers
Maximum size 32,763 bytes ~500 MB per container
Named sections No Yes (named containers)
Multiple data areas Must be in one block Multiple containers
Binary data Awkward Native support (BIT)
Self-documenting No Container names describe content
Discovery Must know structure Can browse containers

Browsing Containers

A program can discover what containers exist in a channel:

           EXEC CICS STARTBROWSE CONTAINER
               CHANNEL('INQUIRY-CHAN')
               BROWSETOKEN(WS-BROWSE-TOKEN)
           END-EXEC.

           PERFORM UNTIL WS-END-BROWSE
               EXEC CICS GETNEXT CONTAINER(WS-CONT-NAME)
                   BROWSETOKEN(WS-BROWSE-TOKEN)
                   RESP(WS-RESP)
               END-EXEC
               IF WS-RESP = DFHRESP(END)
                   SET WS-END-BROWSE TO TRUE
               ELSE
                   DISPLAY 'Container: ' WS-CONT-NAME
               END-IF
           END-PERFORM.

           EXEC CICS ENDBROWSE CONTAINER
               BROWSETOKEN(WS-BROWSE-TOKEN)
           END-EXEC.

25.5 Program Control: Advanced Topics

Both EXEC CICS LINK and EXEC CICS XCTL transfer control to another program, but they behave differently:

LINK creates a new program level (like a CALL in batch COBOL): - The calling program remains in storage - Control returns to the calling program when the linked program finishes - Used for subroutine-style calls - The calling program can examine the COMMAREA after the LINK returns

XCTL (Transfer Control) replaces the current program: - The calling program is released from storage - Control does not return to the calling program - Used for peer-to-peer transfers between application modules - More storage-efficient than LINK

  LINK hierarchy:          XCTL flow:

  Program A                Program A
    |                        |
    +-- LINK --> B           XCTL --> B
    |     |                            |
    |     +-- LINK --> C               XCTL --> C
    |     |                                    |
    |     <-- RETURN                           RETURN
    |                                   (returns to CICS,
    <-- (continues)                     not to A or B)

Decision Guidelines

Use LINK when: - You need the calling program to continue after the called program completes - You are calling a utility or service program - You need to examine results in the COMMAREA after the call - The called program is a DB2 access module

Use XCTL when: - You are transferring to the next logical screen or program in a workflow - The current program has completed its work - You want to free the current program's storage - You are implementing a menu-driven application

Dynamic Program Routing

[IBM Enterprise COBOL] CICS supports dynamic routing of program LINK and XCTL requests to remote CICS regions. This enables workload distribution across a CICSPlex.

      * Link to a program on a remote CICS region
           EXEC CICS LINK PROGRAM('RMTPGM')
               COMMAREA(WS-COMMAREA)
               LENGTH(WS-CA-LENGTH)
               SYSID('CIC2')
           END-EXEC.

The SYSID option specifies the target CICS region. If omitted, the program runs locally. Dynamic routing exits can override the target region at runtime based on workload or other criteria.

DPL allows a CICS program to LINK to a program running on a different CICS region as if it were local. The key restriction is that DPL server programs cannot issue terminal-related commands (SEND MAP, RECEIVE MAP, etc.) because they are not associated with a terminal.

      * DPL call - the remote program cannot use terminal I/O
           EXEC CICS LINK PROGRAM('DBACCESS')
               COMMAREA(WS-DB-REQUEST)
               LENGTH(WS-REQUEST-LEN)
               SYSID('DBCICS')
               SYNCONRETURN
           END-EXEC.

The SYNCONRETURN option causes CICS to take a syncpoint when the remote program returns, committing any database updates independently of the calling program's unit of work.


25.6 CICS and DB2 Integration

The CICS-DB2 Connection

[IBM Enterprise COBOL] When CICS programs need to access DB2 data, the CICS-DB2 adapter manages the connection. The adapter is configured through the CICS DB2CONN resource definition which specifies the DB2 subsystem, connection type, and thread management parameters.

Thread Management

CICS uses DB2 threads to execute SQL statements. There are three types of threads:

  1. Pool threads: Shared threads from a common pool. Used for low-frequency transactions. The thread is released back to the pool after each SQL call.

  2. Entry threads: Dedicated threads defined in a DB2 resource control table (RCT) entry. One entry per transaction. Better performance for high-frequency transactions because the thread is reused.

  3. Command threads: Used by CICS for internal DB2 commands. Not used by application programs.

Writing CICS-DB2 Programs

A CICS program with DB2 access uses standard embedded SQL within CICS API calls. The program is processed by both the CICS translator and the DB2 precompiler:

           EXEC SQL
               SELECT CUST_NAME, CUST_ADDR, CUST_BAL
               INTO :WS-CUST-NAME,
                    :WS-CUST-ADDR,
                    :WS-CUST-BAL
               FROM CUSTOMER
               WHERE CUST_ID = :WS-CUST-ID
           END-EXEC.

           IF SQLCODE = 0
               PERFORM 3100-FORMAT-DISPLAY
           ELSE IF SQLCODE = 100
               MOVE 'Customer not found' TO WS-MSG
           ELSE
               PERFORM 9300-DB2-ERROR
           END-IF.

See example-02-cics-db2.cob for a complete CICS-DB2 program example.

Syncpoint and Two-Phase Commit

[IBM Enterprise COBOL] CICS syncpoint coordinates commits across multiple resource managers (DB2, VSAM, MQ, etc.) using the two-phase commit protocol.

      * Explicit syncpoint - commits all resources
           EXEC CICS SYNCPOINT
           END-EXEC.

      * Rollback - undoes all changes since last syncpoint
           EXEC CICS SYNCPOINT ROLLBACK
           END-EXEC.

Important rules for syncpoints:

  1. EXEC CICS RETURN (without TRANSID) implicitly commits all changes.
  2. EXEC CICS SYNCPOINT commits changes but the task continues.
  3. EXEC CICS SYNCPOINT ROLLBACK undoes changes since the last syncpoint.
  4. A task abend causes automatic rollback.
  5. In a pseudo-conversational program, each interaction is a separate task with its own commit scope.

Two-Phase Commit Flow

When a CICS task updates both DB2 and a VSAM file:

  1. Phase 1 (Prepare): CICS asks each resource manager, "Can you commit?" Each resource manager writes its changes to a log and responds "yes" or "no."
  2. Phase 2 (Commit): If all resource managers respond "yes," CICS tells each to commit. If any responds "no," CICS tells all to rollback.

This protocol guarantees that either all resources are updated or none are, maintaining data integrity across heterogeneous systems.

DB2 Connection Pooling

[IBM Enterprise COBOL] CICS DB2 connection pooling is managed through the CICS DB2CONN and DB2ENTRY resource definitions:

  DB2CONN definition:
    CONNECTST(CONNECTED)
    DB2ID(DB2P)
    NONTERMREL(YES)       * Release thread for non-terminal tasks
    STANDBYMODE(RECONNECT)
    THREADLIMIT(50)       * Maximum pool threads
    THREADWAIT(YES)       * Wait if no thread available

Connection pooling reduces the overhead of establishing new DB2 connections for each transaction. The THREADLIMIT parameter controls the maximum number of concurrent threads, providing back-pressure protection for the DB2 subsystem.


25.7 Temporary Storage Queues: Advanced Usage

Multi-Page Browse Pattern

One of the most common advanced CICS patterns is the multi-page browse, where query results exceed a single screen and the user pages forward and backward through them. TSQs are the standard mechanism for this pattern.

The pattern works as follows:

  1. Execute the database query and write all result records to a TSQ
  2. Display the first page of results from the TSQ
  3. Store the current page number in the COMMAREA
  4. On PF7 (page up) or PF8 (page down), read the appropriate records from the TSQ
  5. On transaction end, delete the TSQ
      * Write query results to TSQ
           PERFORM VARYING WS-TSQ-ITEM FROM 1 BY 1
               UNTIL WS-END-OF-DATA
               EXEC CICS WRITEQ TS
                   QUEUE(WS-TSQ-NAME)
                   FROM(WS-RESULT-RECORD)
                   LENGTH(WS-RECORD-LEN)
               END-EXEC
           END-PERFORM.

      * Read a page of results
           COMPUTE WS-START-ITEM =
               (CA-CURRENT-PAGE - 1) * WS-PAGE-SIZE + 1.

           PERFORM VARYING WS-LINE FROM 1 BY 1
               UNTIL WS-LINE > WS-PAGE-SIZE
               OR WS-START-ITEM + WS-LINE - 1 >
                  WS-TOTAL-ITEMS
               COMPUTE WS-TSQ-ITEM =
                   WS-START-ITEM + WS-LINE - 1
               EXEC CICS READQ TS
                   QUEUE(WS-TSQ-NAME)
                   INTO(WS-RESULT-RECORD)
                   LENGTH(WS-RECORD-LEN)
                   ITEM(WS-TSQ-ITEM)
               END-EXEC
               PERFORM 3200-FORMAT-LINE
           END-PERFORM.

See example-03-queue-processing.cob for the complete implementation.

TSQ Naming Conventions

TSQ names must be unique across the CICS region. Use a naming convention that includes the terminal ID or user ID to prevent collisions:

           STRING 'BROWSE' EIBTRMID
               DELIMITED BY SIZE
               INTO WS-TSQ-NAME.

A common pattern: <prefix><termid> or <prefix><userid> where the prefix identifies the application.

Auxiliary vs Main TSQ

  • Main temporary storage: Stored in CICS main memory. Faster but volatile (lost on CICS restart). Use for small, transient data.
  • Auxiliary temporary storage: Stored on a VSAM dataset. Slower but recoverable. Use for large result sets or when recovery is needed.
      * Write to auxiliary storage
           EXEC CICS WRITEQ TS
               QUEUE(WS-TSQ-NAME)
               FROM(WS-DATA)
               LENGTH(WS-DATA-LEN)
               AUXILIARY
           END-EXEC.

      * Write to main storage (default if MAIN not specified)
           EXEC CICS WRITEQ TS
               QUEUE(WS-TSQ-NAME)
               FROM(WS-DATA)
               LENGTH(WS-DATA-LEN)
               MAIN
           END-EXEC.

TSQ for Inter-Transaction Communication

TSQs can also pass data between different transactions or even different terminals. One transaction writes data, and another reads it. This is useful for notification systems, batch status tracking, and shared lookup caches.


25.8 Transient Data Queues

Intrapartition vs Extrapartition TDQs

Intrapartition TDQs are stored within CICS and can be read by any CICS transaction. They support trigger-level processing, where CICS automatically starts a transaction when the queue depth reaches a specified threshold.

Extrapartition TDQs are mapped to sequential datasets outside CICS. They are used for batch interface files, print output, and log files. They are defined in the CICS DCT (Destination Control Table).

Trigger-Level Processing

Intrapartition TDQs can be configured with a trigger level. When the number of records in the queue reaches the trigger level, CICS automatically initiates a specified transaction:

  DCT Definition:
    DESTID=AUDT
    TYPE=INTRA
    TRANSID=AUDR
    TRIGLEV=100
    FACILTYID=AUDT

When 100 records accumulate in the AUDT queue, CICS automatically starts transaction AUDR, which reads and processes the queued records. This is a powerful pattern for deferred processing.

Audit Logging Pattern

A common use of TDQs is audit logging. Application transactions write audit records to an intrapartition TDQ, and a triggered transaction periodically writes them to a permanent store:

      * Write audit record to TDQ
           MOVE 'TRANSFER' TO AL-ACTION.
           MOVE WS-FROM-ACCT TO AL-FROM-ACCT.
           MOVE WS-TO-ACCT   TO AL-TO-ACCT.
           MOVE WS-AMOUNT    TO AL-AMOUNT.

           EXEC CICS ASKTIME
               ABSTIME(AL-TIMESTAMP)
           END-EXEC.

           EXEC CICS WRITEQ TD
               QUEUE('AUDT')
               FROM(WS-AUDIT-LOG)
               LENGTH(WS-AUDIT-LEN)
           END-EXEC.

TDQ vs TSQ Comparison

Feature TSQ TDQ
Access pattern Random (by item number) Sequential (FIFO)
Rereadable Yes No (destructive read)
Trigger support No Yes (intrapartition)
External interface No Yes (extrapartition)
Typical use Browse data, scratch pad Logging, batch interface

25.9 CICS Security

EXEC CICS VERIFY and SIGNON

[IBM Enterprise COBOL] CICS integrates with RACF (Resource Access Control Facility) or equivalent security products to authenticate users and authorize access to resources.

      * Verify user credentials
           EXEC CICS VERIFY
               USERID(WS-USER-ID)
               PASSWORD(WS-PASSWORD)
               RESP(WS-RESP)
               RESP2(WS-RESP2)
           END-EXEC.

           EVALUATE WS-RESP
               WHEN DFHRESP(NORMAL)
                   PERFORM 2100-LOGIN-SUCCESS
               WHEN DFHRESP(NOTAUTH)
                   MOVE 'Invalid credentials' TO WS-MSG
               WHEN DFHRESP(USERIDERR)
                   MOVE 'Unknown user ID' TO WS-MSG
               WHEN OTHER
                   PERFORM 9400-SECURITY-ERROR
           END-EVALUATE.

Resource Security Checking

Programs can check whether the current user is authorized to perform an action before attempting it:

      * Check if user can update accounts
           EXEC CICS QUERY SECURITY
               RESTYPE('TRANSEC')
               RESID('ACUP')
               RESIDLENGTH(4)
               READ(WS-READ-AUTH)
               UPDATE(WS-UPD-AUTH)
               RESP(WS-RESP)
           END-EXEC.

           IF WS-UPD-AUTH = CVDA(READABLE)
               PERFORM 3000-ALLOW-UPDATE
           ELSE
               MOVE 'Not authorized for updates'
                   TO WS-MSG
               PERFORM 8000-SEND-ERROR
           END-IF.

RACF Integration

CICS security works through RACF resource classes:

  • TCICSTRN: Controls which users can execute which transactions
  • CCICSCMD: Controls CICS system commands
  • DCICSDCT: Controls TDQ access
  • FCICSFCT: Controls file access
  • SCICSTST: Controls TSQ access
  • PCICSPSB: Controls DL/I PSB access

A properly secured CICS application checks authorization at multiple levels: transaction level (can the user run this transaction?), resource level (can the user access this file?), and business level (can the user perform this operation on this account?).


25.10 Advanced Error Handling

Application-Initiated Abend

Sometimes an application must abort the current transaction due to an unrecoverable error. Use EXEC CICS ABEND:

           IF WS-CRITICAL-ERROR
               EXEC CICS ABEND
                   ABCODE('MYAB')
                   CANCEL
               END-EXEC
           END-IF.

The ABCODE is a 4-character code that identifies the type of abend. The CANCEL option prevents any HANDLE ABEND from catching this abend (forces a true abend with a dump).

HANDLE ABEND: PROGRAM vs LABEL

[IBM Enterprise COBOL] CICS provides two forms of abend handling:

HANDLE ABEND PROGRAM routes the abend to a separate error-handling program:

           EXEC CICS HANDLE ABEND
               PROGRAM('ERRPGM')
           END-EXEC.

HANDLE ABEND LABEL routes the abend to a paragraph within the current program:

           EXEC CICS HANDLE ABEND
               LABEL(9500-ABEND-HANDLER)
           END-EXEC.

Important considerations:

  • HANDLE ABEND LABEL is preferred for application-level recovery because it keeps the recovery logic within the program that understands the context.
  • HANDLE ABEND PROGRAM is preferred for generic error handling (logging, notification).
  • After an abend is handled, the program can continue processing, but all CICS resources acquired since the last syncpoint have been released.

PUSH and POP HANDLE

When a program needs to temporarily change abend handling (for example, during a section that might fail in a recoverable way), use PUSH and POP:

      * Save current handle settings
           EXEC CICS PUSH HANDLE
           END-EXEC.

      * Set temporary handler for risky operation
           EXEC CICS HANDLE ABEND
               LABEL(9600-RETRY-HANDLER)
           END-EXEC.

      * Perform risky operation
           PERFORM 5000-RISKY-OPERATION.

      * Restore previous handle settings
           EXEC CICS POP HANDLE
           END-EXEC.

This stack-based approach ensures that error handling is properly scoped and does not interfere with the caller's error handling preferences.

Modern Error Handling with RESP and RESP2

The modern approach avoids HANDLE commands entirely and uses RESP and RESP2 on each CICS command:

           EXEC CICS READ FILE('CUSTFILE')
               INTO(WS-CUSTOMER-REC)
               RIDFLD(WS-CUST-KEY)
               LENGTH(WS-REC-LEN)
               RESP(WS-RESP)
               RESP2(WS-RESP2)
           END-EXEC.

           EVALUATE WS-RESP
               WHEN DFHRESP(NORMAL)
                   CONTINUE
               WHEN DFHRESP(NOTFND)
                   MOVE 'Record not found' TO WS-MSG
               WHEN DFHRESP(DISABLED)
                   MOVE 'File is disabled' TO WS-MSG
               WHEN DFHRESP(IOERR)
                   PERFORM 9700-IO-ERROR
               WHEN OTHER
                   PERFORM 9800-UNEXPECTED-ERROR
           END-EVALUATE.

This approach provides precise, command-level error handling without the control flow complications of HANDLE commands.


25.11 CICS Web Support

EXEC CICS WEB SEND and RECEIVE

[IBM Enterprise COBOL] CICS TS provides native HTTP support, allowing CICS programs to act as web service providers or consumers.

CICS as HTTP Server

A CICS program can receive HTTP requests and send HTTP responses:

      * Receive HTTP request body
           EXEC CICS WEB RECEIVE
               INTO(WS-REQUEST-BODY)
               LENGTH(WS-BODY-LEN)
               MAXLENGTH(32000)
           END-EXEC.

      * Process the request
           PERFORM 5000-PROCESS-REQUEST.

      * Send HTTP response
           EXEC CICS WEB SEND
               FROM(WS-RESPONSE-BODY)
               FROMLENGTH(WS-RESP-LEN)
               MEDIATYPE('application/json')
               STATUSCODE(200)
               STATUSTEXT('OK')
               STATUSLEN(2)
               ACTION(IMMEDIATE)
               CLOSESTATUS(CLOSE)
           END-EXEC.

Extracting HTTP Headers and Query Parameters

      * Get HTTP method
           EXEC CICS WEB READ
               HTTPHEADER('X-Request-Id')
               VALUE(WS-REQUEST-ID)
               VALUELENGTH(WS-HDR-LEN)
               RESP(WS-RESP)
           END-EXEC.

      * Get query parameter
           EXEC CICS WEB READ
               FORMFIELD('accountId')
               VALUE(WS-ACCOUNT-ID)
               VALUELENGTH(WS-FIELD-LEN)
               RESP(WS-RESP)
           END-EXEC.

JSON Data Transformation

[IBM Enterprise COBOL] CICS TS V5.2+ includes JSON transformation support. Programs can convert between COBOL data structures and JSON using the CICS JSON assistant:

      * Parse JSON request into COBOL structure
           EXEC CICS TRANSFORM DATATODATA
               CHANNEL('WEB-CHAN')
               DATCONTAINER('DFHJSON-DATA')
               INCONTAINER('REQUEST-JSON')
               TRANSFORMER('JSONXFRM')
           END-EXEC.

      * Convert COBOL response to JSON
           EXEC CICS TRANSFORM DATATODATA
               CHANNEL('WEB-CHAN')
               DATCONTAINER('RESPONSE-DATA')
               OUTCONTAINER('RESPONSE-JSON')
               TRANSFORMER('JSONXFRM')
           END-EXEC.

CICS as Web Service Provider

To expose a CICS program as a web service, define a URIMAP resource that maps a URL pattern to a CICS program:

  URIMAP Definition:
    NAME(ACCTINQ)
    USAGE(SERVER)
    SCHEME(HTTPS)
    HOST(*)
    PATH(/api/accounts/{id})
    PROGRAM(ACCTPGM)
    PIPELINE(JSONPIPE)

When an HTTP request matches the pattern /api/accounts/{id}, CICS starts the ACCTPGM program. The program reads the HTTP request, processes it, and sends the HTTP response.

See example-06-web-service.cob for a complete web service implementation.


25.12 CICS Transaction Gateway (CTG)

External Access to CICS

[IBM Enterprise COBOL] The CICS Transaction Gateway (CTG) provides a bridge between external applications (Java, .NET, web) and CICS transactions. CTG uses the External Call Interface (ECI) protocol.

Architecture

  Web Browser / Mobile App
       |
  Application Server (Java EE)
       |
  CICS Transaction Gateway
       |
  CICS TS Region
       |
  COBOL Program (DPL-enabled)

How It Works

  1. The external application creates a request with a COMMAREA or channel/containers
  2. CTG sends the request to CICS via ECI
  3. CICS runs the specified program as a DPL call (no terminal I/O)
  4. The program processes the request and returns data in the COMMAREA or containers
  5. CTG returns the response to the external application

COBOL Program Requirements for CTG

Programs called through CTG must be DPL-capable: - No terminal I/O commands (SEND MAP, RECEIVE MAP, etc.) - Must use COMMAREA or channels for all input/output - Should be designed as stateless service programs - Must handle all errors gracefully (no abends that require operator intervention)

       IDENTIFICATION DIVISION.
       PROGRAM-ID. ACCTSERV.
      * DPL-capable service program for CTG access
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  WS-REQUEST.
           05  WS-REQ-TYPE      PIC X(04).
           05  WS-ACCOUNT-ID    PIC X(10).
       01  WS-RESPONSE.
           05  WS-RESP-CODE     PIC 9(04).
           05  WS-CUST-NAME     PIC X(30).
           05  WS-BALANCE       PIC S9(11)V99 COMP-3.
       LINKAGE SECTION.
       01  DFHCOMMAREA          PIC X(100).
       PROCEDURE DIVISION.
           MOVE DFHCOMMAREA TO WS-REQUEST.
           PERFORM 1000-PROCESS-REQUEST.
           MOVE WS-RESPONSE TO DFHCOMMAREA.
           EXEC CICS RETURN END-EXEC.

25.13 CICS MQ Interface

Sending and Receiving MQ Messages

[IBM Enterprise COBOL] CICS programs can interact with IBM MQ (formerly WebSphere MQ) to send and receive messages. This enables asynchronous communication between CICS and other systems.

Putting a Message on a Queue

       01  WS-MQ-MSG            PIC X(2000).
       01  WS-MQ-MSG-LEN        PIC S9(08) COMP VALUE 2000.
       01  WS-MQ-QUEUE          PIC X(48)
                                VALUE 'PAYMENT.REQUEST.QUEUE'.

      * Open MQ queue for output
           EXEC CICS MQ OPEN
               QUEUE(WS-MQ-QUEUE)
               QUEUEHANDLE(WS-Q-HANDLE)
               OPENOPTIONS(MQOO-OUTPUT)
               RESP(WS-RESP)
           END-EXEC.

      * Put message
           EXEC CICS MQ PUT
               QUEUEHANDLE(WS-Q-HANDLE)
               FROM(WS-MQ-MSG)
               DATALENGTH(WS-MQ-MSG-LEN)
               RESP(WS-RESP)
           END-EXEC.

      * Close queue
           EXEC CICS MQ CLOSE
               QUEUEHANDLE(WS-Q-HANDLE)
               RESP(WS-RESP)
           END-EXEC.

Getting a Message from a Queue

      * Open MQ queue for input
           EXEC CICS MQ OPEN
               QUEUE(WS-MQ-QUEUE)
               QUEUEHANDLE(WS-Q-HANDLE)
               OPENOPTIONS(MQOO-INPUT-SHARED)
               RESP(WS-RESP)
           END-EXEC.

      * Get message (with wait)
           EXEC CICS MQ GET
               QUEUEHANDLE(WS-Q-HANDLE)
               INTO(WS-MQ-MSG)
               DATALENGTH(WS-MQ-MSG-LEN)
               RESP(WS-RESP)
           END-EXEC.

           IF WS-RESP = DFHRESP(NORMAL)
               PERFORM 6000-PROCESS-MESSAGE
           END-IF.

MQ and Syncpoint Coordination

MQ operations participate in the CICS syncpoint. This means that MQ PUT operations are not visible to other applications until the task commits, and MQ GET operations return messages to the queue if the task rolls back. This coordination ensures transactional integrity across CICS and MQ.


25.14 Performance Considerations

Transaction Response Time Optimization

CICS applications must be tuned for sub-second response times. Here are the key optimization strategies:

1. Minimize CICS API Calls

Each CICS API call has overhead. Batch multiple operations where possible:

      * Bad: Multiple reads in a loop
           PERFORM VARYING WS-I FROM 1 BY 1
               UNTIL WS-I > 10
               EXEC CICS READQ TS
                   QUEUE(WS-TSQ-NAME)
                   INTO(WS-RECORD)
                   ITEM(WS-I)
               END-EXEC
               MOVE WS-RECORD TO WS-TABLE(WS-I)
           END-PERFORM.

      * Better: Read larger blocks when possible
      * or use a single TSQ item with multiple records

2. Efficient Map Handling

  • Use DATAONLY instead of sending the full map when only data changes
  • Minimize the number of fields sent by initializing the symbolic map to LOW-VALUES (only non-low-value fields are transmitted)
  • Use ACCUM with PAGING for multi-page reports instead of multiple SEND MAPs

3. Avoid Common Bottlenecks

  • Enqueue contention: Keep exclusive locks on shared resources for the minimum time
  • File I/O contention: Use VSAM LSR (Local Shared Resources) buffer pools
  • DB2 thread waits: Monitor thread pool utilization and increase limits if needed
  • TSQ contention: Use unique TSQ names per terminal/user

4. Storage Optimization

  • Keep COMMAREA as small as possible
  • Release unused storage promptly using EXEC CICS FREEMAIN
  • Use EXEC CICS GETMAIN SHARED only when truly needed

Common Performance Anti-Patterns

Anti-Pattern Impact Solution
Conversational programming Holds resources during wait Use pseudo-conversational design
Large COMMAREA Increased memory/network Use channels for large data
Excessive TSQ writes I/O overhead Use main storage for small data
Missing RESP handling Unhandled errors cause abends Always use RESP/RESP2
Sequential file processing Slow for random access Use keyed access paths

25.15 Monitoring and Debugging

CEDF: The Execution Diagnostic Facility

[IBM Enterprise COBOL] CEDF (CICS Execution Diagnostic Facility) is the primary interactive debugging tool for CICS programs. It intercepts CICS API calls and displays their parameters before and after execution.

To start CEDF from a CICS terminal:

  CEDF

Then start your transaction on the same terminal. CEDF intercepts each CICS command and shows: - The command about to be executed - All parameters and their values - The response after execution - The EIBRESP and EIBRESP2 values

CEMT: Master Terminal Transactions

CEMT is the system programmer's primary tool for managing CICS resources:

  CEMT INQUIRE PROGRAM(MYPGM)     - Check program status
  CEMT SET PROGRAM(MYPGM) NEW     - Reload program (NEWCOPY)
  CEMT INQUIRE TASK                - List active tasks
  CEMT SET TASK(12345) PURGE      - Purge a stuck task
  CEMT INQUIRE FILE(CUSTFILE)     - Check file status
  CEMT SET FILE(CUSTFILE) OPEN    - Open a file
  CEMT INQUIRE TSQUEUE            - List TSQs
  CEMT INQUIRE TDQUEUE            - List TDQs

CEBR: TSQ Browser

CEBR allows you to browse the contents of a TSQ:

  CEBR MYTSQ                     - Browse TSQ 'MYTSQ'
  PF7/PF8                        - Page up/down through items
  PF5                            - Display item in hex

CECI: Command-Level Interpreter

CECI lets you execute CICS commands interactively:

  CECI WRITEQ TS QUEUE('TESTQ') FROM('HELLO WORLD')
  CECI READQ TS QUEUE('TESTQ') INTO(&DATA)
  CECI LINK PROGRAM('MYPGM') COMMAREA(&AREA)

CECI is invaluable for testing individual CICS commands without writing a complete program.

CICS Explorer

[IBM Enterprise COBOL] CICS Explorer is an Eclipse-based graphical tool for managing CICS resources. It provides:

  • Real-time resource monitoring
  • Transaction and program management
  • System definition management (CSD)
  • Performance metrics visualization
  • Event management

CICS Explorer has largely replaced the traditional green-screen management interfaces for many tasks, though CEMT and CEDF remain essential for real-time debugging.


25.16 CICS TS V5/V6 Modern Features

Liberty Integration

[IBM Enterprise COBOL] CICS TS V5.1+ includes an embedded Liberty JVM server that allows Java applications to run alongside COBOL programs within CICS. This enables:

  • RESTful web service endpoints using JAX-RS
  • Java EE web applications with access to CICS resources
  • Mixed workloads where Java front-ends call COBOL back-ends via JCICS
  CICS Liberty Architecture:

  Browser/Mobile
       |
  CICS Liberty JVM Server (Java EE)
       |
  JCICS API
       |
  COBOL Programs (LINK)
       |
  DB2 / VSAM / MQ

Node.js Support

CICS TS V5.5+ supports Node.js applications running in CICS. This allows JavaScript developers to:

  • Build modern web APIs that access CICS resources
  • Use npm packages for JSON parsing, HTTP handling, etc.
  • Call COBOL programs using the CICS Node.js API

Cloud and Container Support

CICS TS V5.6+ provides: - CICS Cloud Native: Deploy CICS regions in containers on z/OS Container Extensions (zCX) - CICS Policy-Based Management: Define policies for performance, security, and availability - CICS Event Processing: Emit events to external consumers (Kafka, MQ) when business conditions occur

JSON Web Services Without Coding

CICS TS V5.2+ can automatically transform COBOL COMMAREA data to/from JSON without writing transformation code. The CICS JSON assistant generates a transformer resource from a COBOL copybook:

  1. Define the COBOL data structure in a copybook
  2. Run the DFHJS2LS utility to generate a JSON schema and CICS transformer
  3. Define a URIMAP that maps a URL to the COBOL program with the transformer
  4. CICS automatically converts JSON requests to COMMAREA and COMMAREA responses to JSON

This approach lets existing COBOL programs be exposed as REST APIs with zero code changes to the COBOL program itself.


25.17 CICS Journaling and Recovery

CICS Journal Facility

[IBM Enterprise COBOL] CICS provides a journaling facility for recording transaction activity. Journals capture a record of changes that can be used for audit trails, recovery, and compliance.

      * Write a journal record
           EXEC CICS WRITE JOURNALNUM(1)
               JTYPEID('TX')
               FROM(WS-JOURNAL-REC)
               FLENGTH(LENGTH OF WS-JOURNAL-REC)
               WAIT
               RESP(WS-RESP)
           END-EXEC.

Recovery Concepts

CICS supports several levels of recovery:

  1. Transaction backout: If a task abends, CICS automatically backs out all recoverable resource changes (VSAM files defined as recoverable, DB2 updates, etc.).

  2. Emergency restart: If CICS itself fails, emergency restart replays the system log to recover committed changes and back out uncommitted changes.

  3. Application-level recovery: Programs can use HANDLE ABEND to catch errors and perform application-specific recovery logic.

See example-05-journal-recovery.cob for a complete journaling implementation.


25.18 Putting It All Together

The advanced CICS techniques covered in this chapter form an interconnected toolkit for building enterprise-grade applications:

  • State management (COMMAREA, channels/containers) provides the foundation for complex workflows
  • Program control (LINK, XCTL) enables modular application architecture
  • DB2 integration with syncpoint coordination ensures data integrity
  • Queue management (TSQ, TDQ) supports browsing, logging, and inter-transaction communication
  • Security (RACF integration) protects resources at every level
  • Error handling (RESP/RESP2, HANDLE ABEND) makes applications resilient
  • Web support extends CICS transactions to modern clients
  • MQ integration enables asynchronous enterprise messaging

These techniques are not academic exercises. They represent the actual patterns used in production systems at banks, insurance companies, airlines, and government agencies worldwide. Every COBOL developer working in a mainframe environment will encounter and use these patterns.


Summary

This chapter covered advanced CICS programming techniques that transform basic CICS knowledge into production-level capability. We explored multi-screen application design, sophisticated COMMAREA strategies, the modern channels/containers alternative, and program control patterns. We examined CICS-DB2 integration with two-phase commit, queue management for browsing and logging, comprehensive security implementation, and robust error handling. We extended CICS into the modern world with web services, MQ messaging, and CTG for external access. Finally, we covered performance optimization, debugging tools, and the latest CICS TS features including Liberty and Node.js integration.

The case studies that follow this chapter demonstrate these techniques in realistic scenarios: building a complete online banking application and exposing legacy CICS transactions as RESTful web services.


Next: Exercises, Case Studies, and Further Reading