Example: Running a credit check application with asynchronous processing versus with traditional sequential processing

This example simulates a real-world scenario: a customer applies for a credit card, and a credit check application kicks off to perform checks on the customer. The programs involved in the application will be running both sequentially and asynchronously. This example illustrates the potential of asynchronous processing and its benefits compared with traditional sequential processing.

Before you begin

The source code for this example is available in full on GitHub, where you’ll find two parent programs, ASYNCPNT and SEQPNT, and instructions for running them from a CICS terminal.

About the example

The credit check application checks the customer's name, details and history. Each check has its own program and associated transaction in CICS.
  • SEQPNT calls the involved programs using EXEC CICS LINK.
    Figure 1. SEQPNT - Sequential processing flow
    This diagram illustrates the flow of sequential processing.
  • ASYNCPNT calls the involved programs using EXEC CICS RUN TRANSID.
    Figure 2. ASYNCPNT - Asynchronous processing flow
    This diagram illustrates the flow of asynchronous processing.

Running the example

To run the example, follow the instructions provided with the source code.

Result: The child programs take the same amount of time to complete in both ASYNCPNT and SEQPNT, but ASYNCPNT finishes in roughly half the time thanks to the asynchronous API.

How they differ

Examine in details how asynchronous processing differs from traditional sequential processing:

Getting it done: all at once or bit by bit
The fundamental difference between asynchronous and sequential processing is, simply put, how much you can do at once. Traditional sequential processing only allows you to perform one action at a time; then you have to wait for it to complete (successfully or otherwise) before you can do something else. If one of your actions hangs, or the external service it’s calling is being slow, then the delays stack up quickly. The main body of the sequential SEQPNT program works this way, calling programs one by one using EXEC CICS LINK and waiting for them to complete before retrieving data from them using EXEC CICS GET CONTAINER (the application is using containers to store and retrieve data):

           EXEC CICS LINK PROGRAM ( CREDIT-CHECK )
                          CHANNEL ( MYCHANNEL )
                          RESP    ( COMMAND-RESP )
                          RESP2   ( COMMAND-RESP2 )
           END-EXEC

           EXEC CICS GET CONTAINER (CRDTCHK-CONTAINER)
                           INTO    (CREDIT-CHECK-RESULT)
                           CHANNEL (MYCHANNEL)
                           RESP    (COMMAND-RESP)
                           RESP2   (COMMAND-RESP2)
           END-EXEC

And so on for the other programs that need to run, calling and waiting, calling and waiting.

The ASYNCPNT program, however, looks more like this:

           EXEC CICS RUN TRANSID      (CREDIT-CHECK-TRAN)
                         CHANNEL      (MYCHANNEL)
                         CHILD        (CREDIT-CHECK-TKN)
           END-EXEC

           EXEC CICS RUN TRANSID      (GET-ADDR-TRAN)
                         CHANNEL      (MYCHANNEL)
                         CHILD        (GET-ADDR-TKN)
           END-EXEC

           EXEC CICS RUN TRANSID      (CSSTATUS-TRAN)
                         CHANNEL      (MYCHANNEL)
                         CHILD        (CSSTATUS-TKN)
           END-EXEC

Using the EXEC CICS RUN TRANSID command, multiple programs are kicked off at once, and they’ll run as child transactions of the parent program. Child transactions run separately to the parent program, much like real children, allowing the parent program to continue with anything else it wants to do in the meantime. Child tasks will always run locally to the parent task (that is, in the same CICS region).

Getting results
Getting results in a sequential processing model is as simple as waiting, and waiting, and waiting, because your parent program is blocked until its child program completes. In the asynchronous model, the parent program logic continues until it’s time to find out what the child programs are up to. Use the EXEC CICS FETCH CHILD command to check on the completion status and abend code of any child transaction:

           EXEC CICS FETCH CHILD       (CREDIT-CHECK-TKN)
                           CHANNEL     (CREDIT-CHECK-CHAN)
                           COMPSTATUS  (CHILD-RETURN-STATUS)
                           ABCODE      (CHILD-RETURN-ABCODE)
           END-EXEC

The credit check application doesn’t have any logic that checks if a child transaction completed successfully, which should have been done in real cases, but the response received from a FETCH CHILD command includes completion status and abend code, so you can (and should) ensure that your child transaction was happy and successful.

Once the FETCH CHILD command has completed, retrieve the results of the child transaction using an EXEC CICS GET CONTAINER command, just the same as what would be done in sequential processing:

           EXEC CICS GET CONTAINER (CRDTCHK-CONTAINER)
                           INTO    (CREDIT-CHECK-RESULT)
                           CHANNEL (CREDIT-CHECK-CHAN)
                           RESP    (COMMAND-RESP)
                           RESP2   (COMMAND-RESP2)
           END-EXEC
Parent and child communication

Passing data between parent and child tasks is handled using channels and their containers. When a child task is started using EXEC CICS RUN TRANSID, it will be passed a copy of the channel specified in the command, as well as a copy of all the channel’s containers (and the data within them). As it runs, the child task will update the data in its copy of the channel, while the parent program can continue processing using the original channel; this is what allows the two (or more) tasks to run asynchronously.

Sometimes you won’t even need to use containers: if all you need to know is the completion status of your child tasks, then the EXEC CICS FETCH CHILD command will give you all the information you need.