Case Study 2: Modular Transaction Processing System

Background

Commonwealth Central Bank is replacing its monolithic 28,000-line transaction processing program with a modular architecture. The original program, known internally as "BIGPOST," was written in 1987 and has been modified by over 60 programmers across four decades. It handles every aspect of transaction processing in a single source file: input validation, customer authentication, authorization rule checking, balance posting, fee calculation, audit trail generation, and regulatory reporting. A single change to a fee calculation formula requires recompiling and retesting the entire 28,000-line program, a process that takes three days.

The replacement system, called the Modular Transaction Processing System (MTPS), decomposes the monolith into a main driver program and six specialized subprograms. Each subprogram is independently compilable, testable, and deployable. When the fee calculation formula changes, only the fee subprogram is modified, recompiled, and tested -- a process that takes hours rather than days.


System Architecture

The MTPS consists of seven COBOL programs:

Program ID Role CALL Type
MTPSDRV Main driver -- orchestrates the processing flow N/A (main)
MTPSVAL Transaction validation -- format and data checks Static
MTPSAUTH Authorization -- credit limits, account status, velocity Dynamic
MTPSPOST Balance posting -- applies debits and credits Static
MTPSFEE Fee calculation -- determines applicable fees Dynamic
MTPSAUD Audit trail -- writes audit records Static
MTPSLOG Error logging -- centralized error handling Static

The choice of static vs. dynamic CALL is deliberate:

  • Static calls (MTPSVAL, MTPSPOST, MTPSAUD, MTPSLOG) are used for subprograms that are called on every transaction and change infrequently. Static linking eliminates load-time overhead.
  • Dynamic calls (MTPSAUTH, MTPSFEE) are used for subprograms whose business rules change frequently. Dynamic linking allows these modules to be updated and deployed without relinking the driver or other subprograms.
+-------------------+
|     MTPSDRV       |     Main Driver Program
|  (Orchestrator)   |
+--------+----------+
         |
    +----+----+----+----+----+----+
    |    |    |    |    |    |    |
    v    v    v    v    v    v    v
 MTPS  MTPS MTPS MTPS MTPS MTPS
 VAL   AUTH POST FEE  AUD  LOG

The Communication Interface

All subprograms share a standardized communication area passed via the USING clause. This design allows any subprogram to access the transaction data and return results through a common structure:

      *---------------------------------------------------------------
      * MTPS COMMUNICATION AREA
      * Shared across all MTPS subprograms via CALL...USING
      *---------------------------------------------------------------
       01  WS-MTPS-COMMAREA.
      *    Section 1: Transaction Input Data
           05  MC-TXN-INPUT.
               10  MC-TXN-ID          PIC X(15).
               10  MC-CUSTOMER-ID     PIC X(8).
               10  MC-ACCOUNT-NUMBER  PIC X(10).
               10  MC-TXN-TYPE        PIC X(2).
                   88  MC-DEPOSIT      VALUE "DP".
                   88  MC-WITHDRAWAL   VALUE "WD".
                   88  MC-TRANSFER     VALUE "TF".
                   88  MC-PAYMENT      VALUE "PY".
                   88  MC-FEE-CHARGE   VALUE "FC".
                   88  MC-INTEREST     VALUE "IN".
               10  MC-TXN-AMOUNT      PIC S9(11)V99.
               10  MC-TXN-DATE        PIC 9(8).
               10  MC-TXN-TIME        PIC 9(6).
               10  MC-CHANNEL-CODE    PIC X(3).
               10  MC-BRANCH-CODE     PIC X(4).
               10  MC-DESCRIPTION     PIC X(30).

      *    Section 2: Customer/Account Data (loaded by driver)
           05  MC-ACCOUNT-DATA.
               10  MC-CUSTOMER-NAME   PIC X(30).
               10  MC-ACCOUNT-TYPE    PIC X(2).
                   88  MC-CHECKING     VALUE "CK".
                   88  MC-SAVINGS      VALUE "SV".
                   88  MC-MONEY-MARKET VALUE "MM".
                   88  MC-LOAN         VALUE "LN".
               10  MC-CURRENT-BALANCE PIC S9(11)V99.
               10  MC-AVAILABLE-BAL   PIC S9(11)V99.
               10  MC-DAILY-LIMIT     PIC S9(9)V99.
               10  MC-DAILY-USED      PIC S9(9)V99.
               10  MC-ACCOUNT-STATUS  PIC X(1).
                   88  MC-ACCT-ACTIVE  VALUE "A".
                   88  MC-ACCT-FROZEN  VALUE "F".
                   88  MC-ACCT-CLOSED  VALUE "C".
                   88  MC-ACCT-DORMANT VALUE "D".
               10  MC-LAST-TXN-DATE   PIC 9(8).
               10  MC-OPEN-DATE       PIC 9(8).
               10  MC-TXN-TODAY-COUNT PIC 9(4).

      *    Section 3: Processing Results (set by subprograms)
           05  MC-RESULTS.
               10  MC-VALIDATION-RC   PIC 9(2) VALUE 00.
                   88  MC-VALID        VALUE 00.
                   88  MC-INVALID      VALUE 01 THRU 99.
               10  MC-AUTH-RC          PIC 9(2) VALUE 00.
                   88  MC-AUTHORIZED   VALUE 00.
                   88  MC-AUTH-DENIED  VALUE 01 THRU 99.
               10  MC-POST-RC         PIC 9(2) VALUE 00.
                   88  MC-POSTED       VALUE 00.
                   88  MC-POST-FAILED  VALUE 01 THRU 99.
               10  MC-FEE-RC          PIC 9(2) VALUE 00.
               10  MC-AUDIT-RC        PIC 9(2) VALUE 00.
               10  MC-NEW-BALANCE     PIC S9(11)V99.
               10  MC-FEE-AMOUNT      PIC S9(7)V99.
               10  MC-FEE-TYPE        PIC X(3).
               10  MC-AUTH-MESSAGE    PIC X(50).
               10  MC-ERROR-MESSAGE   PIC X(80).

The Main Driver Program (MTPSDRV)

The driver program orchestrates the processing flow. It reads transactions, loads account data, and calls each subprogram in sequence. If any step fails, subsequent steps are skipped and the error is logged:

       IDENTIFICATION DIVISION.
       PROGRAM-ID. MTPSDRV.

       DATA DIVISION.
       WORKING-STORAGE SECTION.
           COPY MTPSCOMM.

       01  WS-PROGRAM-NAMES.
           05  WS-AUTH-PROGRAM        PIC X(8) VALUE "MTPSAUTH".
           05  WS-FEE-PROGRAM         PIC X(8) VALUE "MTPSFEE".

       01  WS-PROCESSING-FLAGS.
           05  WS-INPUT-EOF           PIC X(1) VALUE "N".
               88  WS-EOF             VALUE "Y".
           05  WS-FATAL-FLAG          PIC X(1) VALUE "N".
               88  WS-FATAL           VALUE "Y".

       01  WS-COUNTERS.
           05  WS-TOTAL-READ          PIC 9(8) VALUE 0.
           05  WS-TOTAL-POSTED        PIC 9(8) VALUE 0.
           05  WS-TOTAL-REJECTED      PIC 9(8) VALUE 0.
           05  WS-TOTAL-FEES          PIC S9(11)V99 VALUE 0.

       PROCEDURE DIVISION.
       0000-MAIN.
           PERFORM 1000-INITIALIZE
           PERFORM 2000-PROCESS-TRANSACTION
               UNTIL WS-EOF OR WS-FATAL
           PERFORM 9000-TERMINATE
           STOP RUN
           .

       1000-INITIALIZE.
           OPEN INPUT  TXN-INPUT-FILE
           OPEN I-O    ACCOUNT-MASTER-FILE
           OPEN OUTPUT AUDIT-TRAIL-FILE
           OPEN OUTPUT ERROR-LOG-FILE
           PERFORM 1100-READ-TRANSACTION
           .

       2000-PROCESS-TRANSACTION.
           ADD 1 TO WS-TOTAL-READ
           INITIALIZE MC-RESULTS

      *---------------------------------------------------------------
      *    STEP 1: VALIDATE TRANSACTION (Static CALL)
      *---------------------------------------------------------------
           CALL "MTPSVAL" USING WS-MTPS-COMMAREA
           IF MC-INVALID
               ADD 1 TO WS-TOTAL-REJECTED
               MOVE "VALIDATION" TO MC-ERROR-MESSAGE
               CALL "MTPSLOG" USING WS-MTPS-COMMAREA
               PERFORM 1100-READ-TRANSACTION
               GO TO 2000-EXIT
           END-IF

      *---------------------------------------------------------------
      *    STEP 2: LOAD ACCOUNT DATA
      *---------------------------------------------------------------
           PERFORM 2100-LOAD-ACCOUNT
           IF MC-POST-RC NOT = 00
               ADD 1 TO WS-TOTAL-REJECTED
               CALL "MTPSLOG" USING WS-MTPS-COMMAREA
               PERFORM 1100-READ-TRANSACTION
               GO TO 2000-EXIT
           END-IF

      *---------------------------------------------------------------
      *    STEP 3: AUTHORIZE TRANSACTION (Dynamic CALL)
      *---------------------------------------------------------------
           CALL WS-AUTH-PROGRAM USING WS-MTPS-COMMAREA
               ON EXCEPTION
                   DISPLAY "CANNOT LOAD AUTHORIZATION MODULE"
                   MOVE "AUTH MODULE NOT FOUND"
                       TO MC-ERROR-MESSAGE
                   SET WS-FATAL TO TRUE
                   GO TO 2000-EXIT
           END-CALL

           IF MC-AUTH-DENIED
               ADD 1 TO WS-TOTAL-REJECTED
               MOVE "AUTHORIZATION DENIED"
                   TO MC-ERROR-MESSAGE
               CALL "MTPSLOG" USING WS-MTPS-COMMAREA
               CALL "MTPSAUD" USING WS-MTPS-COMMAREA
               PERFORM 1100-READ-TRANSACTION
               GO TO 2000-EXIT
           END-IF

      *---------------------------------------------------------------
      *    STEP 4: POST TRANSACTION (Static CALL)
      *---------------------------------------------------------------
           CALL "MTPSPOST" USING WS-MTPS-COMMAREA
           IF MC-POST-FAILED
               ADD 1 TO WS-TOTAL-REJECTED
               CALL "MTPSLOG" USING WS-MTPS-COMMAREA
               PERFORM 1100-READ-TRANSACTION
               GO TO 2000-EXIT
           END-IF

      *---------------------------------------------------------------
      *    STEP 5: CALCULATE FEES (Dynamic CALL)
      *---------------------------------------------------------------
           CALL WS-FEE-PROGRAM USING WS-MTPS-COMMAREA
               ON EXCEPTION
                   DISPLAY "WARNING: FEE MODULE NOT AVAILABLE"
                   MOVE 0 TO MC-FEE-AMOUNT
                   MOVE 00 TO MC-FEE-RC
           END-CALL

           IF MC-FEE-AMOUNT > 0
               ADD MC-FEE-AMOUNT TO WS-TOTAL-FEES
               PERFORM 2200-POST-FEE
           END-IF

      *---------------------------------------------------------------
      *    STEP 6: WRITE AUDIT TRAIL (Static CALL)
      *---------------------------------------------------------------
           CALL "MTPSAUD" USING WS-MTPS-COMMAREA

           ADD 1 TO WS-TOTAL-POSTED
           PERFORM 1100-READ-TRANSACTION
           .

       2000-EXIT.
           EXIT.

Loading Account Data

The driver loads account data from the master file into the communication area before calling the authorization and posting subprograms:

       2100-LOAD-ACCOUNT.
           MOVE MC-ACCOUNT-NUMBER TO AMR-ACCOUNT-NUMBER
           READ ACCOUNT-MASTER-FILE
               KEY IS AMR-ACCOUNT-NUMBER
               INVALID KEY
                   MOVE 23 TO MC-POST-RC
                   STRING "ACCOUNT NOT FOUND: "
                       MC-ACCOUNT-NUMBER
                       DELIMITED SIZE
                       INTO MC-ERROR-MESSAGE
                   GO TO 2100-EXIT
           END-READ

           MOVE AMR-CUSTOMER-NAME  TO MC-CUSTOMER-NAME
           MOVE AMR-ACCOUNT-TYPE   TO MC-ACCOUNT-TYPE
           MOVE AMR-CURRENT-BALANCE
                                   TO MC-CURRENT-BALANCE
           MOVE AMR-AVAILABLE-BAL  TO MC-AVAILABLE-BAL
           MOVE AMR-DAILY-LIMIT    TO MC-DAILY-LIMIT
           MOVE AMR-DAILY-USED     TO MC-DAILY-USED
           MOVE AMR-ACCOUNT-STATUS TO MC-ACCOUNT-STATUS
           MOVE AMR-LAST-TXN-DATE  TO MC-LAST-TXN-DATE
           MOVE AMR-OPEN-DATE      TO MC-OPEN-DATE
           MOVE AMR-TXN-TODAY-COUNT
                                   TO MC-TXN-TODAY-COUNT
           .

       2100-EXIT.
           EXIT.

The Validation Subprogram (MTPSVAL)

The validation subprogram checks the transaction data for format and content errors. It operates on the communication area without performing any file I/O:

       IDENTIFICATION DIVISION.
       PROGRAM-ID. MTPSVAL.

       DATA DIVISION.
       LINKAGE SECTION.
           COPY MTPSCOMM REPLACING
               WS-MTPS-COMMAREA BY LS-COMMAREA.

       PROCEDURE DIVISION USING LS-COMMAREA.
       0000-MAIN.
           MOVE 00 TO MC-VALIDATION-RC

      *    Check transaction ID
           IF MC-TXN-ID = SPACES
               MOVE 01 TO MC-VALIDATION-RC
               MOVE "BLANK TRANSACTION ID"
                   TO MC-ERROR-MESSAGE
               GOBACK
           END-IF

      *    Check customer ID
           IF MC-CUSTOMER-ID = SPACES
               MOVE 02 TO MC-VALIDATION-RC
               MOVE "BLANK CUSTOMER ID"
                   TO MC-ERROR-MESSAGE
               GOBACK
           END-IF

      *    Check account number
           IF MC-ACCOUNT-NUMBER = SPACES
               MOVE 03 TO MC-VALIDATION-RC
               MOVE "BLANK ACCOUNT NUMBER"
                   TO MC-ERROR-MESSAGE
               GOBACK
           END-IF

      *    Check transaction type
           IF NOT (MC-DEPOSIT OR MC-WITHDRAWAL
               OR MC-TRANSFER OR MC-PAYMENT
               OR MC-FEE-CHARGE OR MC-INTEREST)
               MOVE 04 TO MC-VALIDATION-RC
               STRING "INVALID TXN TYPE: " MC-TXN-TYPE
                   DELIMITED SIZE INTO MC-ERROR-MESSAGE
               GOBACK
           END-IF

      *    Check amount is non-zero
           IF MC-TXN-AMOUNT = ZEROS
               MOVE 05 TO MC-VALIDATION-RC
               MOVE "ZERO TRANSACTION AMOUNT"
                   TO MC-ERROR-MESSAGE
               GOBACK
           END-IF

      *    Check date is valid
           IF MC-TXN-DATE < 20200101
           OR MC-TXN-DATE > 20991231
               MOVE 06 TO MC-VALIDATION-RC
               MOVE "TRANSACTION DATE OUT OF RANGE"
                   TO MC-ERROR-MESSAGE
               GOBACK
           END-IF

           GOBACK
           .

The Authorization Subprogram (MTPSAUTH)

The authorization subprogram implements the bank's business rules for approving or declining transactions. It is dynamically called because authorization rules change frequently (new regulations, adjusted limits, fraud pattern updates):

       IDENTIFICATION DIVISION.
       PROGRAM-ID. MTPSAUTH.

       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  WS-REMAINING-LIMIT        PIC S9(9)V99.
       01  WS-VELOCITY-THRESHOLD     PIC 9(4) VALUE 50.
       01  WS-DORMANT-THRESHOLD      PIC 9(3) VALUE 180.
       01  WS-DAYS-INACTIVE           PIC 9(5).

       LINKAGE SECTION.
           COPY MTPSCOMM REPLACING
               WS-MTPS-COMMAREA BY LS-COMMAREA.

       PROCEDURE DIVISION USING LS-COMMAREA.
       0000-MAIN.
           MOVE 00 TO MC-AUTH-RC
           MOVE SPACES TO MC-AUTH-MESSAGE

      *---------------------------------------------------------------
      *    Rule 1: Account must be active
      *---------------------------------------------------------------
           EVALUATE TRUE
               WHEN MC-ACCT-FROZEN
                   MOVE 10 TO MC-AUTH-RC
                   MOVE "ACCOUNT IS FROZEN" TO MC-AUTH-MESSAGE
                   GOBACK
               WHEN MC-ACCT-CLOSED
                   MOVE 11 TO MC-AUTH-RC
                   MOVE "ACCOUNT IS CLOSED" TO MC-AUTH-MESSAGE
                   GOBACK
               WHEN MC-ACCT-DORMANT
                   IF MC-WITHDRAWAL OR MC-TRANSFER
                       MOVE 12 TO MC-AUTH-RC
                       MOVE "DORMANT ACCT - DEBITS BLOCKED"
                           TO MC-AUTH-MESSAGE
                       GOBACK
                   END-IF
           END-EVALUATE

      *---------------------------------------------------------------
      *    Rule 2: Sufficient funds for withdrawals/transfers
      *---------------------------------------------------------------
           IF MC-WITHDRAWAL OR MC-TRANSFER
               IF MC-TXN-AMOUNT > MC-AVAILABLE-BAL
                   MOVE 20 TO MC-AUTH-RC
                   MOVE "INSUFFICIENT AVAILABLE BALANCE"
                       TO MC-AUTH-MESSAGE
                   GOBACK
               END-IF
           END-IF

      *---------------------------------------------------------------
      *    Rule 3: Daily limit check
      *---------------------------------------------------------------
           IF MC-WITHDRAWAL OR MC-TRANSFER
               COMPUTE WS-REMAINING-LIMIT =
                   MC-DAILY-LIMIT - MC-DAILY-USED
               IF MC-TXN-AMOUNT > WS-REMAINING-LIMIT
                   MOVE 30 TO MC-AUTH-RC
                   MOVE "DAILY TRANSACTION LIMIT EXCEEDED"
                       TO MC-AUTH-MESSAGE
                   GOBACK
               END-IF
           END-IF

      *---------------------------------------------------------------
      *    Rule 4: Velocity check (too many transactions today)
      *---------------------------------------------------------------
           IF MC-TXN-TODAY-COUNT > WS-VELOCITY-THRESHOLD
               MOVE 40 TO MC-AUTH-RC
               MOVE "TRANSACTION VELOCITY EXCEEDED"
                   TO MC-AUTH-MESSAGE
               GOBACK
           END-IF

      *---------------------------------------------------------------
      *    Rule 5: Large transaction review
      *---------------------------------------------------------------
           IF MC-TXN-AMOUNT > 10000.00
           AND (MC-WITHDRAWAL OR MC-TRANSFER)
               IF MC-CHANNEL-CODE = "ATM"
               OR MC-CHANNEL-CODE = "MOB"
                   MOVE 50 TO MC-AUTH-RC
                   MOVE "LARGE TXN ON REMOTE CHANNEL"
                       TO MC-AUTH-MESSAGE
                   GOBACK
               END-IF
           END-IF

      *    All rules passed
           MOVE "AUTHORIZED" TO MC-AUTH-MESSAGE
           GOBACK
           .

The Posting Subprogram (MTPSPOST)

The posting subprogram applies the transaction to the account balance. It receives the communication area, computes the new balance, and returns the result without performing file I/O (the driver handles the master file updates):

       IDENTIFICATION DIVISION.
       PROGRAM-ID. MTPSPOST.

       DATA DIVISION.
       LINKAGE SECTION.
           COPY MTPSCOMM REPLACING
               WS-MTPS-COMMAREA BY LS-COMMAREA.

       PROCEDURE DIVISION USING LS-COMMAREA.
       0000-MAIN.
           MOVE 00 TO MC-POST-RC

           EVALUATE TRUE
               WHEN MC-DEPOSIT
               WHEN MC-INTEREST
                   ADD MC-TXN-AMOUNT TO MC-CURRENT-BALANCE
                       ON SIZE ERROR
                           MOVE 01 TO MC-POST-RC
                           MOVE "SIZE ERROR ON CREDIT"
                               TO MC-ERROR-MESSAGE
                           GOBACK
                   END-ADD
                   ADD MC-TXN-AMOUNT TO MC-AVAILABLE-BAL

               WHEN MC-WITHDRAWAL
               WHEN MC-PAYMENT
               WHEN MC-FEE-CHARGE
                   SUBTRACT MC-TXN-AMOUNT
                       FROM MC-CURRENT-BALANCE
                       ON SIZE ERROR
                           MOVE 02 TO MC-POST-RC
                           MOVE "SIZE ERROR ON DEBIT"
                               TO MC-ERROR-MESSAGE
                           GOBACK
                   END-SUBTRACT
                   SUBTRACT MC-TXN-AMOUNT
                       FROM MC-AVAILABLE-BAL
                   ADD MC-TXN-AMOUNT TO MC-DAILY-USED

               WHEN MC-TRANSFER
                   SUBTRACT MC-TXN-AMOUNT
                       FROM MC-CURRENT-BALANCE
                       ON SIZE ERROR
                           MOVE 03 TO MC-POST-RC
                           MOVE "SIZE ERROR ON TRANSFER"
                               TO MC-ERROR-MESSAGE
                           GOBACK
                   END-SUBTRACT
                   SUBTRACT MC-TXN-AMOUNT
                       FROM MC-AVAILABLE-BAL
                   ADD MC-TXN-AMOUNT TO MC-DAILY-USED
           END-EVALUATE

           MOVE MC-CURRENT-BALANCE TO MC-NEW-BALANCE
           ADD 1 TO MC-TXN-TODAY-COUNT
           MOVE MC-TXN-DATE TO MC-LAST-TXN-DATE

           GOBACK
           .

The Fee Calculation Subprogram (MTPSFEE)

Fee rules change several times per year as the bank adjusts its pricing. The dynamic CALL allows the fee module to be updated independently:

       IDENTIFICATION DIVISION.
       PROGRAM-ID. MTPSFEE.

       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  WS-FEE-SCHEDULE.
           05  WS-ATM-FOREIGN-FEE    PIC 9(3)V99 VALUE 3.00.
           05  WS-WIRE-OUTGOING-FEE  PIC 9(3)V99 VALUE 25.00.
           05  WS-WIRE-INCOMING-FEE  PIC 9(3)V99 VALUE 15.00.
           05  WS-OVERDRAFT-FEE      PIC 9(3)V99 VALUE 35.00.
           05  WS-EXCESS-TXN-FEE     PIC 9(3)V99 VALUE 5.00.
           05  WS-EXCESS-TXN-LIMIT   PIC 9(2)    VALUE 6.

       LINKAGE SECTION.
           COPY MTPSCOMM REPLACING
               WS-MTPS-COMMAREA BY LS-COMMAREA.

       PROCEDURE DIVISION USING LS-COMMAREA.
       0000-MAIN.
           MOVE 00 TO MC-FEE-RC
           MOVE 0  TO MC-FEE-AMOUNT
           MOVE SPACES TO MC-FEE-TYPE

      *    Rule 1: Foreign ATM fee
           IF MC-CHANNEL-CODE = "ATM"
           AND MC-BRANCH-CODE(1:2) NOT = "OW"
               MOVE WS-ATM-FOREIGN-FEE TO MC-FEE-AMOUNT
               MOVE "FAT" TO MC-FEE-TYPE
           END-IF

      *    Rule 2: Wire transfer fees
           IF MC-TRANSFER
               IF MC-TXN-AMOUNT > 0
                   MOVE WS-WIRE-OUTGOING-FEE TO MC-FEE-AMOUNT
                   MOVE "WRO" TO MC-FEE-TYPE
               ELSE
                   MOVE WS-WIRE-INCOMING-FEE TO MC-FEE-AMOUNT
                   MOVE "WRI" TO MC-FEE-TYPE
               END-IF
           END-IF

      *    Rule 3: Overdraft fee (balance went negative)
           IF MC-NEW-BALANCE < 0
           AND MC-CURRENT-BALANCE >= 0
               ADD WS-OVERDRAFT-FEE TO MC-FEE-AMOUNT
               MOVE "OVD" TO MC-FEE-TYPE
           END-IF

      *    Rule 4: Excess transaction fee for savings
           IF MC-SAVINGS
           AND (MC-WITHDRAWAL OR MC-TRANSFER)
           AND MC-TXN-TODAY-COUNT > WS-EXCESS-TXN-LIMIT
               ADD WS-EXCESS-TXN-FEE TO MC-FEE-AMOUNT
               MOVE "EXT" TO MC-FEE-TYPE
           END-IF

           GOBACK
           .

The Audit Trail Subprogram (MTPSAUD)

Every transaction -- whether approved or rejected -- generates an audit record:

       IDENTIFICATION DIVISION.
       PROGRAM-ID. MTPSAUD.

       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  WS-AUDIT-RECORD.
           05  AR-TIMESTAMP          PIC X(26).
           05  AR-TXN-ID             PIC X(15).
           05  AR-CUSTOMER-ID        PIC X(8).
           05  AR-ACCOUNT-NUMBER     PIC X(10).
           05  AR-TXN-TYPE           PIC X(2).
           05  AR-TXN-AMOUNT         PIC S9(11)V99.
           05  AR-NEW-BALANCE        PIC S9(11)V99.
           05  AR-FEE-AMOUNT         PIC S9(7)V99.
           05  AR-VALIDATION-RC      PIC 9(2).
           05  AR-AUTH-RC            PIC 9(2).
           05  AR-POST-RC            PIC 9(2).
           05  AR-AUTH-MESSAGE       PIC X(50).
           05  AR-CHANNEL            PIC X(3).
           05  AR-FILLER             PIC X(18).

       LINKAGE SECTION.
           COPY MTPSCOMM REPLACING
               WS-MTPS-COMMAREA BY LS-COMMAREA.

       PROCEDURE DIVISION USING LS-COMMAREA.
       0000-MAIN.
           MOVE 00 TO MC-AUDIT-RC
           MOVE FUNCTION CURRENT-DATE TO AR-TIMESTAMP
           MOVE MC-TXN-ID          TO AR-TXN-ID
           MOVE MC-CUSTOMER-ID     TO AR-CUSTOMER-ID
           MOVE MC-ACCOUNT-NUMBER  TO AR-ACCOUNT-NUMBER
           MOVE MC-TXN-TYPE        TO AR-TXN-TYPE
           MOVE MC-TXN-AMOUNT      TO AR-TXN-AMOUNT
           MOVE MC-NEW-BALANCE     TO AR-NEW-BALANCE
           MOVE MC-FEE-AMOUNT      TO AR-FEE-AMOUNT
           MOVE MC-VALIDATION-RC   TO AR-VALIDATION-RC
           MOVE MC-AUTH-RC         TO AR-AUTH-RC
           MOVE MC-POST-RC        TO AR-POST-RC
           MOVE MC-AUTH-MESSAGE   TO AR-AUTH-MESSAGE
           MOVE MC-CHANNEL-CODE    TO AR-CHANNEL

           WRITE AUDIT-FILE-RECORD FROM WS-AUDIT-RECORD
           IF WS-AUDIT-STATUS NOT = "00"
               MOVE 01 TO MC-AUDIT-RC
           END-IF

           GOBACK
           .

JCL for the Modular System

//MTPSPROC JOB (ACCT),'MODULAR TXN POST',
//         CLASS=A,MSGCLASS=X,NOTIFY=&SYSUID
//*
//* MODULAR TRANSACTION PROCESSING SYSTEM
//* DRIVER + 6 SUBPROGRAMS
//*
//PROCESS  EXEC PGM=MTPSDRV,REGION=256M
//STEPLIB  DD DSN=PROD.LOADLIB,DISP=SHR
//*         ^^^^ Contains MTPSDRV, MTPSVAL, MTPSPOST,
//*              MTPSAUD, MTPSLOG (statically linked)
//*              AND MTPSAUTH, MTPSFEE (dynamically loaded)
//*
//* INPUT: DAILY TRANSACTION FILE
//TXNINP   DD DSN=BANK.DAILY.TRANSACTIONS(0),DISP=SHR
//*
//* I-O: ACCOUNT MASTER FILE
//ACCTMAST DD DSN=BANK.ACCOUNT.MASTER,DISP=SHR
//*
//* OUTPUT: AUDIT TRAIL
//AUDTRL   DD DSN=BANK.AUDIT.TRAIL(+1),
//         DISP=(NEW,CATLG,DELETE),
//         SPACE=(CYL,(50,20)),
//         DCB=(RECFM=FB,LRECL=200,BLKSIZE=0)
//*
//* OUTPUT: ERROR LOG
//ERRLOG   DD DSN=BANK.MTPS.ERRORS(+1),
//         DISP=(NEW,CATLG,DELETE),
//         SPACE=(CYL,(5,2)),
//         DCB=(RECFM=FB,LRECL=200,BLKSIZE=0)
//*
//SYSOUT   DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*

Using CANCEL for Dynamic Module Refresh

When the authorization or fee modules are updated during a batch window, the CANCEL statement can be used to unload the old version so the next CALL loads the updated one:

      *    Check if module refresh is requested
      *    (signaled by a control record in the input)
           IF TXN-TYPE = "RF"
               CANCEL WS-AUTH-PROGRAM
               CANCEL WS-FEE-PROGRAM
               DISPLAY "DYNAMIC MODULES REFRESHED"
               PERFORM 1100-READ-TRANSACTION
               GO TO 2000-EXIT
           END-IF

The CANCEL statement releases the storage occupied by the dynamically loaded module and causes the next CALL to reload it from the load library. This is a powerful deployment technique: the operations team can replace the MTPSAUTH load module in the load library and then submit a "refresh" control record through the transaction feed to trigger the reload -- all without stopping the batch job.


BY REFERENCE vs. BY CONTENT

All MTPS subprograms receive the communication area BY REFERENCE (the default), which means the subprogram operates directly on the caller's copy of the data. Changes made by the subprogram are immediately visible to the driver:

      *    BY REFERENCE (default) -- subprogram modifies caller's data
       CALL "MTPSPOST" USING BY REFERENCE WS-MTPS-COMMAREA

If a subprogram should not be able to modify the input data (for example, the audit subprogram should not change the transaction data while writing the audit record), BY CONTENT could be used:

      *    BY CONTENT -- subprogram gets a copy, cannot modify original
       CALL "MTPSAUD" USING BY CONTENT WS-MTPS-COMMAREA

However, BY CONTENT creates a copy of the entire communication area on every call, which adds overhead for large structures. The MTPS design uses BY REFERENCE for all calls and relies on the subprogram contracts to ensure that each module only modifies its designated output fields.


Testing Individual Subprograms

Each subprogram can be tested independently using a test driver program:

       IDENTIFICATION DIVISION.
       PROGRAM-ID. TESTAUTH.
      *    Test driver for MTPSAUTH authorization module

       DATA DIVISION.
       WORKING-STORAGE SECTION.
           COPY MTPSCOMM.

       PROCEDURE DIVISION.
       0000-TEST.
      *    Test Case 1: Normal withdrawal within limits
           INITIALIZE WS-MTPS-COMMAREA
           SET MC-WITHDRAWAL TO TRUE
           MOVE 500.00 TO MC-TXN-AMOUNT
           MOVE 10000.00 TO MC-AVAILABLE-BAL
           MOVE 5000.00 TO MC-DAILY-LIMIT
           MOVE 1000.00 TO MC-DAILY-USED
           SET MC-ACCT-ACTIVE TO TRUE
           MOVE 5 TO MC-TXN-TODAY-COUNT

           CALL "MTPSAUTH" USING WS-MTPS-COMMAREA

           IF MC-AUTHORIZED
               DISPLAY "TEST 1 PASSED: AUTHORIZED"
           ELSE
               DISPLAY "TEST 1 FAILED: RC=" MC-AUTH-RC
                   " MSG=" MC-AUTH-MESSAGE
           END-IF

      *    Test Case 2: Insufficient funds
           INITIALIZE WS-MTPS-COMMAREA
           SET MC-WITHDRAWAL TO TRUE
           MOVE 500.00 TO MC-TXN-AMOUNT
           MOVE 200.00 TO MC-AVAILABLE-BAL
           SET MC-ACCT-ACTIVE TO TRUE

           CALL "MTPSAUTH" USING WS-MTPS-COMMAREA

           IF MC-AUTH-RC = 20
               DISPLAY "TEST 2 PASSED: CORRECTLY DENIED"
           ELSE
               DISPLAY "TEST 2 FAILED: RC=" MC-AUTH-RC
           END-IF

      *    Test Case 3: Frozen account
           INITIALIZE WS-MTPS-COMMAREA
           SET MC-DEPOSIT TO TRUE
           MOVE 100.00 TO MC-TXN-AMOUNT
           SET MC-ACCT-FROZEN TO TRUE

           CALL "MTPSAUTH" USING WS-MTPS-COMMAREA

           IF MC-AUTH-RC = 10
               DISPLAY "TEST 3 PASSED: FROZEN REJECTED"
           ELSE
               DISPLAY "TEST 3 FAILED: RC=" MC-AUTH-RC
           END-IF

           STOP RUN
           .

This ability to test each subprogram in isolation is one of the primary benefits of the modular architecture. With the monolithic BIGPOST program, testing a single authorization rule change required setting up the entire file environment (input file, master file, audit file, error log) and processing through thousands of transactions to reach the specific scenario. With MTPSAUTH, the test driver sets up a single communication area and calls the module directly.


Lessons Learned

1. The Communication Area Is the Contract

The MTPS communication area (MTPSCOMM copybook) serves as the formal interface contract between all modules. Changes to this structure must be coordinated across all subprograms, which is why it is defined in a copybook rather than duplicated in each program. Any change to the copybook triggers recompilation of all programs that include it.

2. Dynamic CALL Enables Independent Deployment

The authorization and fee modules can be updated, compiled, and deployed to the load library without touching the driver or other subprograms. This reduced the deployment cycle for fee changes from three days (full regression test of BIGPOST) to four hours (unit test of MTPSFEE plus a targeted integration test).

3. Static CALL Is Faster for High-Volume Modules

Validation (MTPSVAL) is called for every transaction -- potentially millions of times per batch run. The static CALL eliminates the overhead of program loading and searching the load library on each invocation. Performance testing showed that static calls were 15% faster than dynamic calls for high-frequency modules.

4. GOBACK Preserves WORKING-STORAGE State for Dynamic Calls

When a dynamically called subprogram uses GOBACK, its WORKING-STORAGE retains its values between calls (in the non-initial state). This is useful for MTPSFEE, which keeps the fee schedule in working storage and does not need to reinitialize it on every call. However, if the module is CANCELed and re-called, working storage is reinitialized.

5. ON EXCEPTION Is Essential for Dynamic Calls

The ON EXCEPTION clause on dynamic CALLs catches the case where the load module is not found in the load library. Without this clause, a missing module would cause an abend. With it, the driver can log the error, set a fatal flag, and shut down gracefully.


Discussion Questions

  1. The communication area uses a flat structure (no nested subprograms or object orientation). What would the design look like if COBOL supported object-oriented features like methods and encapsulation? How would the interface change?

  2. The driver currently processes one transaction at a time. If the system needed to support "grouped" transactions (such as a transfer that involves a debit from one account and a credit to another), how would the communication area and calling sequence need to change?

  3. The fee module is called after the posting module. What would happen if a fee calculation needed information that was only available after posting (such as the resulting balance)? Is the current calling sequence correct for this requirement?

  4. How would you add a new subprogram (for example, a regulatory reporting module that checks transactions against OFAC sanctions lists) to the system? What changes are needed in the driver, the communication area, and the JCL?

  5. In a CICS online environment, the same MTPS modules could be called from a CICS transaction rather than a batch driver. What changes would be needed to make the subprograms work in both batch and online environments? Consider file access, working storage, and the communication mechanism.