• Jobs
  • Support
Sign in
  • Jobs
  • Support
    • Developer Overview
  • Business Context

    • Business Overview
    • Business Glossary
    • Business Rules Reference
  • Architecture Documentation

    • System Architecture
    • Database Schema
    • Integration Points
    • Data Flow
      • Overview
      • Policy Creation Data Flow
      • Renewal Processing Data Flow
      • Claims Management Data Flow
      • Batch Processing Flow
      • Error Handling Data Flows
      • Transaction Boundaries
      • Database Commit Strategy
  • Program Reference

    • Insurance.cbl (INSMASTR)
  • Sign in
DocumentationCode Explorer
Loading...
Hypercubic

© Copyright 2025. All rights reserved.

On this page

  1. Overview
  2. Policy Creation Data Flow
  3. Renewal Processing Data Flow
  4. Claims Management Data Flow
  5. Batch Processing Flow
  6. Error Handling Data Flows
  7. Transaction Boundaries
  8. Database Commit Strategy

Technical Data Flow Documentation

Overview

The INSMASTR program implements sophisticated data flow patterns for insurance operations, processing three distinct transaction types through a unified batch processing framework. Each data flow follows a consistent pattern of input validation, business logic execution, database operations, and output generation, while maintaining strict transaction boundaries and error handling protocols.

Processing Architecture

The system operates in a batch mode, reading sequential input files and processing records through validation, calculation, and persistence layers. All database operations occur within controlled transaction boundaries with periodic commits to balance performance and recovery requirements.

Key Data Flow Characteristics

  • Sequential Processing: Records processed in order from flat files
  • Transaction Isolation: CS (Cursor Stability) isolation level for optimal concurrency
  • Commit Frequency: Every 500 records to manage transaction log size
  • Error Tolerance: Individual record failures don't abort the entire batch
  • Referential Integrity: Database enforces relationships between CUSTOMER, POLICY, CLAIM, and PROVIDER tables
  • Audit Trail: All database operations record timestamp and user information

Policy Creation Data Flow

Policy creation represents the entry point for new customer applications. This flow transforms raw application data into validated, risk-assessed, and priced insurance policies stored in the database.

Input Data Sources

Primary Input: POLFILE (Policy Input File)

  • DD Name: POLFILE
  • Record Length: 800 bytes
  • Organization: Sequential
  • Format: Fixed-length records with header, detail, and trailer records

Input Data Elements (Lines 313-383):

  • Customer demographics (number, name, DOB, gender, SSN)
  • Contact information (address, phone, email)
  • Insurance requirements (type, coverage amount, deductible, copay)
  • Payment terms (frequency, method)
  • Risk factors (smoker status, pre-existing conditions, occupation, income)
  • Additional data (beneficiary, agent code, referral source)

JCL Parameters:

  • Processing mode parameter from SYSIN (must be 'POLICY' or 'ALL')

Data Flow Diagram

Loading diagram...

Processing Steps

Step 1: Input Reading and Record Type Detection (Lines 1145-1168)

The program reads records sequentially from POLFILE. Each record contains a 2-byte record type indicator:

  • 'HD': Header record (skipped)
  • 'DT': Detail record (processed)
  • 'TR': Trailer record (skipped)

Only detail records proceed to validation.

Step 2: Validation (Section 2110-VALIDATE-POLICY-INPUT, Lines 1179-1329)

Validation Rules:

  • Customer number: Must be numeric and greater than zero
  • Customer name: Must not be spaces
  • Date of birth: Must be valid date format (YYYY-MM-DD)
  • Age: Calculated age must be between 18 and 85 (WS-MIN-AGE to WS-MAX-AGE)
  • SSN: Must be 9 digits, not all zeros
  • Insurance type: Must match valid types (HEALTH, LIFE, AUTO, PROPERTY, DENTAL, VISION)
  • Coverage amount: Must be greater than zero and not exceed WS-MAX-COVERAGE (999,999,999)
  • Email: Must contain '@' symbol

Database Interactions: None at this stage

Output: Sets validation flag; on failure, populates error message and invokes error handler

Step 3: Age Calculation (Section 2111-CALCULATE-CUSTOMER-AGE, Lines 1335-1351)

Algorithm:

Customer Age = Current Year - Birth Year
IF Current Month < Birth Month THEN
    Customer Age = Customer Age - 1
ELSE IF Current Month = Birth Month THEN
    IF Current Day < Birth Day THEN
        Customer Age = Customer Age - 1

Uses: COBOL intrinsic function CURRENT-DATE for system date

Result: Stored in WS-CUSTOMER-AGE for subsequent risk and premium calculations

Step 4: Duplicate Check (Section 2120-CHECK-DUPLICATE-POLICY, Lines 1357-1382)

Database Query (Lines 1358-1365):

SELECT COUNT(*)
INTO :WS-DUPLICATE-COUNT
FROM POLICY_TABLE
WHERE CUSTOMER_NUMBER = :POL-CUSTOMER-NUMBER
  AND INSURANCE_TYPE = :POL-INSURANCE-TYPE
  AND POLICY_STATUS = 'ACTIVE'

Business Rule: One customer cannot have multiple active policies of the same insurance type

Outcome:

  • Count = 0: Proceed to risk calculation
  • Count > 0: Reject with error code 2002 "DUPLICATE ACTIVE POLICY FOUND"

Commit Point: None (read-only query)

Step 5: Risk Score Calculation (Section 2130-CALCULATE-RISK-SCORE, Lines 1388-1444)

Risk Components (additive scoring, 0-100 scale):

  1. Age Factor (Lines 1394-1401):

    • Age < 25: +20 points
    • Age > 65: +30 points
    • Age 56-65: +15 points
  2. Gender Factor (Lines 1406-1408):

    • Male (POL-GENDER = 'M'): +5 points
  3. Smoker Factor (Lines 1413-1415):

    • Smoker (POL-SMOKER-FLAG = 'Y'): +25 points
  4. Health Factor (Lines 1420-1422):

    • Pre-existing conditions (POL-PRE-EXISTING-CONDITIONS = 'Y'): +20 points
  5. Occupation Factor (Lines 1427-1433):

    • Table search in WS-OCCUPATION-RATE-TABLE
    • Construction worker: +50 points
    • Mining/extraction: +60 points
    • Pilot/aviation: +40 points
    • Police/firefighter: +35 points
    • Office worker: +10 points
    • Default (not found): +10 points

Final Adjustment (Lines 1438-1444):

  • Maximum cap: 100 points
  • Minimum floor: 0 points

Database Interactions: None (pure calculation)

Output: WS-RISK-SCORE stored for premium calculation and database insert

Step 6: Premium Calculation (Section 2140-CALCULATE-POLICY-PREMIUM, Lines 1450-1551)

Multi-Stage Calculation:

Stage 1: Base Premium (Lines 1454-1473)

Base Premium = Coverage Amount × Insurance Type Rate

Insurance Type Rates:
- HEALTH:    0.0040 (0.4%)
- LIFE:      0.0020 (0.2%)
- AUTO:      0.0080 (0.8%)
- PROPERTY:  0.0030 (0.3%)
- DENTAL:    0.0015 (0.15%)
- VISION:    0.0010 (0.1%)

Stage 2: Deductible Adjustment (Lines 1478-1481)

IF Deductible > 0 THEN
    Deductible Ratio = Deductible / Coverage Amount
    Base Premium = Base Premium × (1 - (Deductible Ratio × 0.30))

Higher deductibles reduce premium by up to 30% of the ratio.

Stage 3: Age Factor Application (Lines 1486-1495)

Uses indexed table search (WS-AGE-RATE-TABLE) with 7 age brackets:

  • Ages 18-25: ×0.800 (20% discount)
  • Ages 26-35: ×1.000 (baseline)
  • Ages 36-45: ×1.200 (20% increase)
  • Ages 46-55: ×1.500 (50% increase)
  • Ages 56-65: ×2.000 (100% increase)
  • Ages 66-75: ×3.000 (200% increase)
  • Ages 76-85: ×4.000 (300% increase)

Stage 4: Risk Adjustment (Lines 1500-1501)

Risk Adjustment = Base Premium × (Risk Score / 100)

Adds proportional premium based on risk (0% to 100% of base).

Stage 5: Discounts (Lines 1506-1518)

IF Payment Frequency = 'A' (Annual) THEN
    Annual Discount = Premium × 0.05 (5%)

IF Coverage Amount > $500,000 THEN
    Large Coverage Discount = Premium × 0.10 (10%)

Total Discount = Sum of applicable discounts

Stage 6: State Tax (Lines 1523-1534)

Uses indexed table search (WS-STATE-RATE-TABLE) with state-specific rates:

  • New York (NY): 8.875%
  • California (CA): 8.250%
  • Texas (TX): 6.250%
  • Florida (FL): 7.000%
  • Default (state not found): 8.000%
Tax Amount = (Base Premium + Risk Adjustment - Discounts) × State Tax Rate

Stage 7: Final Premium (Lines 1539-1551)

Final Premium = Base Premium + Risk Adjustment - Total Discount + Tax Amount + $25.00

Processing Fee: $25.00 (fixed)

IF Payment Frequency = 'M' (Monthly) THEN
    Monthly Premium = Final Premium / 12

Database Interactions: None (pure calculation)

Output: WS-FINAL-PREMIUM stored in HV-PREMIUM-AMOUNT for database insert

Step 7: Customer Record Creation (Section 2150-CREATE-UPDATE-CUSTOMER, Lines 1557-1635)

Database Operation: MERGE (upsert pattern)

SQL Statement (Lines 1597-1629):

MERGE INTO CUSTOMER_TABLE AS C
USING (VALUES(
    :HV-CUST-NUMBER,
    :HV-CUST-NAME,
    :HV-CUST-DOB,
    :HV-CUST-SSN,
    :HV-CUST-GENDER,
    :HV-CUST-MARITAL-STATUS,
    :HV-CUST-ADDRESS,
    :HV-CUST-PHONE,
    :HV-CUST-EMAIL,
    :HV-CUST-STATUS,
    :HV-CUST-RISK-PROFILE,
    :HV-CUST-CREDIT-SCORE
)) AS S(CUSTOMER_NUMBER, CUSTOMER_NAME, DATE_OF_BIRTH, SSN,
         GENDER, MARITAL_STATUS, ADDRESS, PHONE, EMAIL, STATUS,
         RISK_PROFILE, CREDIT_SCORE)
ON C.CUSTOMER_NUMBER = S.CUSTOMER_NUMBER
WHEN MATCHED THEN
    UPDATE SET
        CUSTOMER_NAME = S.CUSTOMER_NAME,
        ADDRESS = S.ADDRESS,
        PHONE = S.PHONE,
        EMAIL = S.EMAIL,
        LAST_UPDATE_DATE = CURRENT_TIMESTAMP,
        UPDATED_BY = :WS-PROGRAM-NAME
WHEN NOT MATCHED THEN
    INSERT (CUSTOMER_NUMBER, CUSTOMER_NAME, DATE_OF_BIRTH, SSN,
            GENDER, MARITAL_STATUS, ADDRESS, PHONE, EMAIL, STATUS,
            RISK_PROFILE, CREDIT_SCORE, CREATED_DATE, CREATED_BY)
    VALUES (S.CUSTOMER_NUMBER, S.CUSTOMER_NAME, S.DATE_OF_BIRTH, S.SSN,
            S.GENDER, S.MARITAL_STATUS, S.ADDRESS, S.PHONE, S.EMAIL,
            'ACTIVE', S.RISK_PROFILE, S.CREDIT_SCORE,
            CURRENT_TIMESTAMP, :WS-PROGRAM-NAME)

Risk Profile Assignment (Lines 1582-1589):

IF Risk Score < 30 THEN
    Risk Profile = 'LOW'
ELSE IF Risk Score >= 30 AND Risk Score < 70 THEN
    Risk Profile = 'MEDIUM'
ELSE
    Risk Profile = 'HIGH'

Commit Point: No immediate commit; marked for batch commit

Error Handling: SQLCODE checked; non-zero triggers rollback and error logging

Step 8: Policy Number Generation and Insert (Section 2160-INSERT-POLICY-RECORD, Lines 1641-1727)

Sequence Generation (Lines 1645-1649):

SELECT NEXT VALUE FOR POLICY_SEQ
INTO :HV-POLICY-NUMBER
FROM SYSIBM.SYSDUMMY1

Generates unique 15-digit policy number.

Date Calculations (Lines 1657-1668):

Policy Start Date = Current Date
Policy Term Months = 12 (standard one-year policy)
Policy End Date = Add 12 months to Start Date

Initialization (Lines 1673-1678):

Policy Status = 'ACTIVE'
Deductible Met = $0.00
Out of Pocket Met = $0.00
Claims Count = 0
Renewal Count = 0

Database Insert (Lines 1697-1719):

INSERT INTO POLICY_TABLE
(POLICY_NUMBER, CUSTOMER_NUMBER, CUSTOMER_NAME,
 INSURANCE_TYPE, POLICY_START_DATE, POLICY_END_DATE,
 POLICY_TERM_MONTHS, POLICY_STATUS,
 COVERAGE_AMOUNT, DEDUCTIBLE_AMOUNT, DEDUCTIBLE_MET,
 OUT_OF_POCKET_MAX, OUT_OF_POCKET_MET,
 PREMIUM_AMOUNT, PAYMENT_FREQUENCY, PAYMENT_METHOD,
 RISK_SCORE, FRAUD_SCORE, CLAIMS_COUNT, RENEWAL_COUNT,
 CREATED_DATE, CREATED_BY)
VALUES
(:HV-POLICY-NUMBER, :HV-CUSTOMER-NUMBER, :HV-CUSTOMER-NAME,
 :HV-INSURANCE-TYPE, :HV-POLICY-START-DATE, :HV-POLICY-END-DATE,
 :HV-POLICY-TERM-MONTHS, :HV-POLICY-STATUS,
 :HV-COVERAGE-AMOUNT, :HV-DEDUCTIBLE-AMOUNT, :HV-DEDUCTIBLE-MET,
 :HV-OUT-OF-POCKET-MAX, :HV-OUT-OF-POCKET-MET,
 :HV-PREMIUM-AMOUNT, :HV-PAYMENT-FREQUENCY, :HV-PAYMENT-METHOD,
 :HV-RISK-SCORE, :HV-FRAUD-SCORE, :HV-CLAIMS-COUNT, :HV-RENEWAL-COUNT,
 :HV-CREATED-DATE, :HV-CREATED-BY)

Commit Point: Increments WS-COMMIT-COUNT; actual commit when counter reaches 500

Error Handling: SQLCODE checked; duplicate key or constraint violations trigger rollback

Step 9: Output Generation (Section 2170-WRITE-POLICY-OUTPUT, Lines 1733-1760)

POLOUT File Record (Lines 1737-1747):

Transaction Type: 'POLICY'
Policy Number: Generated 15-digit number
Customer Number: 10-digit customer ID
Customer Name: 50 characters
Insurance Type: 10 characters
Premium Amount: Calculated premium (9,999,999.99)
Status: 'CREATED'
Processing Timestamp: Current date/time

RPTFILE Report Line (Lines 797-804):

Report Detail Format:
Policy Number | Customer Name | Insurance Type | Premium | Status

Counters Updated:

  • WS-POL-PROCESS-COUNT: Incremented
  • WS-TOTAL-PROCESS-COUNT: Incremented

Commit Point: Checked after output; commit if threshold reached

Transaction Boundaries

Begin Transaction: Implicit at program start or after previous commit Commit Points:

  • Every 500 successful database operations (WS-COMMIT-FREQUENCY)
  • Final commit during program termination (9000-FINALIZE-PROGRAM)

Rollback Points:

  • Any SQLCODE error (except +100 "not found")
  • Critical errors in error handler

Renewal Processing Data Flow

Policy renewal creates a new policy record with updated terms while maintaining linkage to the original policy, enabling complete policy history tracking.

Input Data Sources

Primary Input: RENFILE (Renewal Input File)

  • DD Name: RENFILE
  • Record Length: 600 bytes
  • Organization: Sequential

Input Data Elements (Lines 389-438):

  • Policy identification (policy number, customer number)
  • Renewal type (standard, upgrade, downgrade, multi-year)
  • Current expiration date
  • Renewal term in months (12, 24, or 36)
  • Requested coverage and deductible changes
  • Rider additions
  • Payment method updates
  • Auto-renewal preference
  • Loyalty and no-claims years
  • Multi-policy flag
  • Discount codes

Data Flow Diagram

Loading diagram...

Processing Steps

Step 1: Validation (Section 3110-VALIDATE-RENEWAL-INPUT, Lines 1773-1899)

Validation Rules:

  • Policy number: Must be numeric and > 0
  • Customer number: Must be numeric and > 0
  • Renewal type: Must be 'ST', 'UP', 'DN', or 'MY'
  • Renewal term: Must be 12, 24, or 36 months
  • Requested coverage: If specified, must be > 0

Database Interactions: None

Output: Validation flag set; errors logged to ERRFILE

Step 2: Existing Policy Retrieval (Section 3120-GET-EXISTING-POLICY, Lines 1905-1942)

Database Query (Lines 1906-1920):

SELECT CUSTOMER_NUMBER, CUSTOMER_NAME,
       INSURANCE_TYPE, COVERAGE_AMOUNT,
       PREMIUM_AMOUNT, DEDUCTIBLE_AMOUNT,
       POLICY_STATUS, POLICY_END_DATE,
       RISK_SCORE, CLAIMS_COUNT, RENEWAL_COUNT
INTO :HV-CUSTOMER-NUMBER, :HV-CUSTOMER-NAME,
     :HV-INSURANCE-TYPE, :HV-COVERAGE-AMOUNT,
     :HV-PREMIUM-AMOUNT, :HV-DEDUCTIBLE-AMOUNT,
     :HV-POLICY-STATUS, :HV-POLICY-END-DATE,
     :HV-RISK-SCORE, :HV-CLAIMS-COUNT,
     :HV-RENEWAL-COUNT
FROM POLICY_TABLE
WHERE POLICY_NUMBER = :REN-POLICY-NUMBER

Business Rules (Lines 1925-1942):

  • SQLCODE +100: Policy not found → Error 3002
  • Policy status ≠ 'ACTIVE': Cannot renew inactive policy → Error 3003

Commit Point: None (read-only)

Step 3: Renewal Premium Calculation (Section 3130-CALCULATE-RENEWAL-PREMIUM, Lines 1948-2045)

Base Calculation by Renewal Type (Lines 1952-1986):

STANDARD RENEWAL:
    New Base Premium = Current Premium × 1.03 (+3% annual increase)

UPGRADE:
    IF Requested Coverage > Current Coverage THEN
        New Base Premium = Current Premium × 1.25 (+25% adjustment)
        IF Requested Coverage specified THEN
            Recalculate: New Coverage × Original Rate × 1.25
        END IF
    END IF

DOWNGRADE:
    IF Requested Coverage < Current Coverage THEN
        New Base Premium = Current Premium × 0.75 (-25% adjustment)
        IF Requested Coverage specified THEN
            Recalculate: New Coverage × Original Rate × 0.75
        END IF
    END IF

MULTI-YEAR:
    Annual Premium = Current Premium × 1.03
    New Base Premium = Annual Premium × (Term Months / 12) × 0.95
    (5% discount for multi-year commitment)

Loyalty Discount (Lines 1991-1998):

IF REN-LOYALTY-YEARS > 0 THEN
    Loyalty Discount % = REN-LOYALTY-YEARS × 1%
    IF Loyalty Discount % > 15% THEN
        Loyalty Discount % = 15% (cap)
    END IF
    Loyalty Discount Amount = New Base Premium × Loyalty Discount %
END IF

No-Claims Discount (Lines 2003-2011):

Database Check:
SELECT CLAIMS_COUNT
INTO :HV-CLAIMS-COUNT
FROM POLICY_TABLE
WHERE POLICY_NUMBER = :REN-POLICY-NUMBER

IF CLAIMS_COUNT = 0 AND REN-NO-CLAIMS-YEARS > 0 THEN
    No-Claims Discount % = REN-NO-CLAIMS-YEARS × 2%
    IF No-Claims Discount % > 20% THEN
        No-Claims Discount % = 20% (cap)
    END IF
    No-Claims Discount Amount = New Base Premium × No-Claims Discount %
END IF

Multi-Policy Discount (Lines 2016-2030):

Database Query:
SELECT COUNT(*)
INTO :WS-POLICY-COUNT
FROM POLICY_TABLE
WHERE CUSTOMER_NUMBER = :HV-CUSTOMER-NUMBER
  AND POLICY_STATUS = 'ACTIVE'

IF Policy Count >= 2 THEN
    Multi-Policy Discount = New Base Premium × 10%
END IF

Deductible Change Adjustment (Lines 2035-2045):

IF Requested Deductible > Current Deductible THEN
    Premium Adjustment = -5% (higher deductible reduces premium)
ELSE IF Requested Deductible < Current Deductible THEN
    Premium Adjustment = +5% (lower deductible increases premium)
END IF

Final Renewal Premium = New Base Premium - All Discounts + Adjustment

Database Interactions:

  • SELECT for claims count (read-only)
  • SELECT COUNT for multi-policy (read-only)

Commit Point: None (calculations only)

Step 4: New Policy Creation (Section 3140-CREATE-RENEWAL-POLICY, Lines 2051-2139)

Sequence Generation (Lines 2055-2059):

SELECT NEXT VALUE FOR POLICY_SEQ
INTO :HV-POLICY-NUMBER
FROM SYSIBM.SYSDUMMY1

Date Calculations (Lines 2065-2079):

New Policy Start Date = Old Policy End Date (seamless transition)
New Policy Term = Renewal Term Months (12, 24, or 36)
New Policy End Date = Start Date + Term Months

Field Population (Lines 2084-2101):

Copy from old policy:
- Customer Number
- Customer Name
- Insurance Type
- Risk Score (unless upgrade/downgrade)

Update values:
- Coverage Amount (if changed)
- Deductible Amount (if changed)
- Premium Amount (newly calculated)
- Payment Method (if changed)

Reset usage counters:
- Deductible Met = $0.00
- Out of Pocket Met = $0.00
- Claims Count = 0

Increment:
- Renewal Count = Old Renewal Count + 1

Link policies:
- Renewal From Policy = Old Policy Number

Database Insert (Lines 2107-2139):

INSERT INTO POLICY_TABLE
(POLICY_NUMBER, CUSTOMER_NUMBER, CUSTOMER_NAME,
 INSURANCE_TYPE, POLICY_START_DATE, POLICY_END_DATE,
 POLICY_TERM_MONTHS, POLICY_STATUS,
 COVERAGE_AMOUNT, DEDUCTIBLE_AMOUNT, DEDUCTIBLE_MET,
 OUT_OF_POCKET_MAX, OUT_OF_POCKET_MET,
 PREMIUM_AMOUNT, PAYMENT_FREQUENCY, PAYMENT_METHOD,
 RISK_SCORE, FRAUD_SCORE, CLAIMS_COUNT, RENEWAL_COUNT,
 RENEWAL_FROM_POLICY,
 CREATED_DATE, CREATED_BY)
VALUES
(...new policy values including RENEWAL_FROM_POLICY link...)

Commit Point: Marked for batch commit; actual commit at 500-record threshold

Step 5: Old Policy Update (Section 3150-UPDATE-OLD-POLICY, Lines 2145-2159)

Database Update (Lines 2146-2153):

UPDATE POLICY_TABLE
SET POLICY_STATUS = 'RENEWED',
    RENEWAL_TO_POLICY = :HV-POLICY-NUMBER,
    LAST_UPDATE_DATE = CURRENT_TIMESTAMP,
    UPDATED_BY = :WS-PROGRAM-NAME
WHERE POLICY_NUMBER = :REN-POLICY-NUMBER

Purpose:

  • Marks old policy as renewed (prevents further claims or renewals)
  • Creates bidirectional link: old policy points to new, new points to old
  • Maintains complete policy history for audit and analytics

Commit Point: Same transaction as new policy insert; both commit together

Step 6: Output Generation (Section 3160-WRITE-RENEWAL-OUTPUT, Lines 2165-2191)

RENOUT File Record (Lines 2169-2178):

Transaction Type: 'RENEWAL'
Old Policy Number: Original 15-digit number
New Policy Number: Generated 15-digit number
Customer Number: 10-digit customer ID
New Premium Amount: Calculated renewal premium
Status: 'RENEWED'
Processing Timestamp: Current date/time

Report Line: Detail line written to RPTFILE showing renewal success

Counters Updated:

  • WS-REN-PROCESS-COUNT
  • WS-TOTAL-PROCESS-COUNT
  • WS-COMMIT-COUNT

Transaction Boundaries

Single Transaction Scope:

  1. New policy INSERT
  2. Old policy UPDATE

Both operations commit together, ensuring atomic renewal. If either fails, both rollback.

Commit Frequency: Every 500 successful renewal operations


Claims Management Data Flow

Claims processing implements sophisticated fraud detection and payment calculation logic, updating policy usage tracking while generating payment instructions.

Input Data Sources

Primary Input: CLMFILE (Claims Input File)

  • DD Name: CLMFILE
  • Record Length: 900 bytes
  • Organization: Sequential

Input Data Elements (Lines 444-523):

  • Claim identification (claim number, policy number)
  • Customer information
  • Claim type (medical, hospital, emergency, dental, vision, auto, property)
  • Date information (incident date, claim date, report date)
  • Financial (claim amount, currency)
  • Provider details (code, name, type, network status, tax ID)
  • Medical details (diagnosis, procedure, DRG, admission/discharge dates)
  • Auto claim details (police report, other party, damage estimate)
  • Documentation flags (receipt, invoice, prescription, X-ray, lab results)
  • Approval codes (pre-authorization, referral, override)

Data Flow Diagram

Loading diagram...

Processing Steps

Step 1: Validation (Section 4110-VALIDATE-CLAIM-INPUT, Lines 2204-2377)

Validation Rules:

  • Claim number: Must not be spaces
  • Policy number: Must be numeric and > 0
  • Claim type: Must match valid types
  • Incident date: Cannot be in future
  • Claim date: Must be >= incident date
  • Claim amount: Must be > 0
  • Provider code: Must not be spaces (if medical claim)

Database Interactions: None

Step 2: Policy Retrieval and Validation (Section 4120-GET-CLAIM-POLICY, Lines 2383-2430)

Database Query (Lines 2384-2398):

SELECT POLICY_STATUS, POLICY_START_DATE, POLICY_END_DATE,
       COVERAGE_AMOUNT, DEDUCTIBLE_AMOUNT, DEDUCTIBLE_MET,
       OUT_OF_POCKET_MAX, OUT_OF_POCKET_MET,
       COPAY_PCT, CLAIMS_COUNT
INTO :HV-POLICY-STATUS, :HV-POLICY-START-DATE, :HV-POLICY-END-DATE,
     :HV-COVERAGE-AMOUNT, :HV-DEDUCTIBLE-AMOUNT, :HV-DEDUCTIBLE-MET,
     :HV-OUT-OF-POCKET-MAX, :HV-OUT-OF-POCKET-MET,
     :WS-COPAY-PERCENTAGE, :HV-CLAIMS-COUNT
FROM POLICY_TABLE
WHERE POLICY_NUMBER = :CLM-POLICY-NUMBER

Business Rules:

  • Policy must exist (SQLCODE ≠ +100)
  • Policy status must be 'ACTIVE'
  • Incident date must be between policy start and end dates

Commit Point: None (read-only)

Step 3: Duplicate Claim Check (Section 4130-CHECK-DUPLICATE-CLAIM, Lines 2436-2448)

Database Query (Lines 2437-2442):

SELECT COUNT(*)
INTO :WS-DUPLICATE-COUNT
FROM CLAIM_TABLE
WHERE CLAIM_NUMBER = :CLM-CLAIM-NUMBER

Business Rule: Same claim number cannot be submitted twice

Commit Point: None (read-only)

Step 4: Fraud Detection (Section 4140-FRAUD-DETECTION, Lines 2454-2561)

Component 1: Frequency Analysis (Lines 2460-2474):

SELECT COUNT(*)
INTO :WS-ROW-COUNT
FROM CLAIM_TABLE
WHERE CUSTOMER_NUMBER = :CLM-CUSTOMER-NUMBER
  AND CLAIM_DATE >= CURRENT_DATE - 30 DAYS

Scoring:
- Count > 3: +25 fraud points (very high frequency)
- Count > 1: +10 fraud points (high frequency)
- Count <= 1: +0 points (normal)

Component 2: Amount Analysis (Lines 2479-2485):

Scoring:
- Claim Amount > $50,000: +15 fraud points (very large claim)
- Claim Amount > $25,000: +10 fraud points (large claim)
- Claim Amount <= $25,000: +0 points (normal)

Component 3: Provider History (Lines 2490-2508):

SELECT FRAUD_SCORE, ACTIVE_FLAG
INTO :HV-PROV-FRAUD-SCORE, :HV-PROV-ACTIVE-FLAG
FROM PROVIDER_TABLE
WHERE PROVIDER_CODE = :CLM-PROVIDER-CODE

Scoring:
- Provider Fraud Score > 50: +20 fraud points (high-risk provider)
- Provider Active Flag = 'N': +30 fraud points (inactive provider)
- Otherwise: +0 points

Component 4: Pattern Detection (Lines 2513-2526):

SELECT COUNT(*)
INTO :WS-ROW-COUNT
FROM CLAIM_TABLE
WHERE CUSTOMER_NUMBER = :CLM-CUSTOMER-NUMBER
  AND CLAIM_TYPE = :CLM-CLAIM-TYPE
  AND CLAIM_AMOUNT = :CLM-CLAIM-AMOUNT
  AND CLAIM_DATE >= CURRENT_DATE - 90 DAYS

Scoring:
- Identical claims found: +20 fraud points (suspicious pattern)
- No matches: +0 points

Component 5: Timing Analysis (Lines 2531-2535):

Day of Week Check (using FUNCTION DAY-OF-WEEK):
- Weekend incident (Saturday/Sunday): +5 fraud points
- Weekday: +0 points

Fraud Score Decision Logic (Lines 2542-2561):

Total Fraud Score = Sum of all components (0-100+)

IF Fraud Score >= 70 THEN
    Claim Status = 'UNDER REVIEW'
    Approval Status = 'FRAUD INVESTIGATION'
    Fraud Flag = 'Y'
    Investigation Flag = 'Y'
    Insurance Payment = $0.00
    Patient Responsibility = $0.00
    Skip payment calculation

ELSE IF Fraud Score >= 50 AND Fraud Score < 70 THEN
    Claim Status = 'PROCESSING'
    Approval Status = 'MANUAL REVIEW REQUIRED'
    Fraud Flag = 'N'
    Investigation Flag = 'N'
    Insurance Payment = $0.00
    Patient Responsibility = $0.00
    Skip payment calculation

ELSE IF Fraud Score < 50 THEN
    Proceed to payment calculation
    IF Claim Amount <= $5,000 THEN
        Approval Status = 'AUTO-APPROVED'
    ELSE
        Approval Status = 'PENDING APPROVAL'
    END IF
END IF

Database Interactions:

  • SELECT COUNT from CLAIM_TABLE (2 queries)
  • SELECT from PROVIDER_TABLE (1 query)

Commit Point: None (read-only fraud analysis)

Step 5: Payment Calculation (Section 4150-CALCULATE-CLAIM-PAYMENT, Lines 2567-2665)

Only executes if fraud score < 50

Stage 1: Approved Amount (Lines 2577-2585):

Approved Amount = Claim Amount (initial assignment)
Insurance Pays = $0.00 (initialize)
Patient Pays = $0.00 (initialize)

Stage 2: Deductible Application (Lines 2591-2603):

Calculate Remaining Deductible:
    Remaining Deductible = Policy Deductible Amount - Deductible Met

IF Remaining Deductible > 0 THEN
    IF Approved Amount >= Remaining Deductible THEN
        Deductible Applied = Remaining Deductible
    ELSE
        Deductible Applied = Approved Amount (claim doesn't cover full deductible)
    END IF

    Patient Pays = Patient Pays + Deductible Applied
    Approved Amount = Approved Amount - Deductible Applied
END IF

Example:

Claim: $10,000
Policy Deductible: $2,000
Already Met: $500

Remaining Deductible = $2,000 - $500 = $1,500
Deductible Applied = $1,500
Patient Pays = $0 + $1,500 = $1,500
Approved Amount = $10,000 - $1,500 = $8,500

Stage 3: Copay/Coinsurance (Lines 2608-2620):

Default Copay Percentage = 20% (if not specified in policy)

Copay Amount = Approved Amount × Copay Percentage
Patient Pays = Patient Pays + Copay Amount
Coinsurance Applied = Copay Amount (for reporting)
Insurance Pays = Approved Amount - Copay Amount

Continuing example:

Approved Amount (after deductible) = $8,500
Copay Percentage = 20%

Copay Amount = $8,500 × 0.20 = $1,700
Patient Pays = $1,500 + $1,700 = $3,200
Insurance Pays = $8,500 - $1,700 = $6,800

Stage 4: Out-of-Pocket Maximum (Lines 2625-2633):

Calculate Remaining Out-of-Pocket:
    Remaining OOP = Policy OOP Maximum - OOP Already Met

IF Patient Pays > Remaining OOP THEN
    Excess Amount = Patient Pays - Remaining OOP
    Patient Pays = Remaining OOP (capped at limit)
    Insurance Pays = Insurance Pays + Excess Amount (insurance covers excess)
END IF

Continuing example:

Policy OOP Maximum = $5,000
Already Met = $3,000

Remaining OOP = $5,000 - $3,000 = $2,000
Patient Pays = $3,200
Excess = $3,200 - $2,000 = $1,200

Patient Pays = $2,000 (capped)
Insurance Pays = $6,800 + $1,200 = $8,000

Stage 5: Coverage Limit Check (Lines 2641-2645):

IF Insurance Pays > Policy Coverage Amount THEN
    Insurance Pays = Policy Coverage Amount (cap at policy limit)
    Recalculate Patient Pays = Claim Amount - Insurance Pays
END IF

Final calculation result:

Original Claim Amount: $10,000
Insurance Pays: $8,000
Patient Responsibility: $2,000
Deductible Applied: $1,500
Copay Applied: $1,700
Coinsurance Applied: $1,700

Database Interactions: None (pure calculation)

Step 6: Claim Record Creation (Section 4160-INSERT-CLAIM-RECORD, Lines 2671-2755)

Sequence Generation (Lines 2675-2679):

SELECT NEXT VALUE FOR CLAIM_SEQ
INTO :HV-CLAIM-ID
FROM SYSIBM.SYSDUMMY1

Generates unique 10-digit claim ID.

Database Insert (Lines 2718-2747):

INSERT INTO CLAIM_TABLE
(CLAIM_ID, CLAIM_NUMBER, POLICY_NUMBER, CUSTOMER_NUMBER,
 CLAIM_TYPE, INCIDENT_DATE, CLAIM_DATE,
 CLAIM_AMOUNT, APPROVED_AMOUNT,
 DEDUCTIBLE_APPLIED, COPAY_APPLIED, COINSURANCE_APPLIED,
 INSURANCE_PAID, PATIENT_RESPONSIBILITY,
 CLAIM_STATUS, APPROVAL_STATUS, PAYMENT_STATUS,
 DENIAL_REASON, PROVIDER_CODE, PROVIDER_NAME,
 DIAGNOSIS_CODE, PROCEDURE_CODE,
 FRAUD_FLAG, FRAUD_SCORE, INVESTIGATION_FLAG,
 CREATED_DATE, CREATED_BY)
VALUES
(:HV-CLAIM-ID, :HV-CLAIM-NUMBER, :HV-CLM-POLICY-NUMBER,
 :HV-CLM-CUSTOMER-NUMBER, :HV-CLAIM-TYPE,
 :HV-INCIDENT-DATE, :HV-CLAIM-DATE,
 :HV-CLAIM-AMOUNT, :HV-APPROVED-AMOUNT,
 :HV-DEDUCTIBLE-APPLIED, :HV-COPAY-APPLIED,
 :HV-COINSURANCE-APPLIED, :HV-INSURANCE-PAID,
 :HV-PATIENT-RESPONSIBILITY, :HV-CLAIM-STATUS,
 :HV-APPROVAL-STATUS, 'PENDING', :WS-DENIAL-REASON,
 :HV-PROVIDER-CODE, :HV-PROVIDER-NAME,
 :HV-DIAGNOSIS-CODE, :HV-PROCEDURE-CODE,
 :HV-FRAUD-FLAG, :HV-CLM-FRAUD-SCORE,
 :HV-INVESTIGATION-FLAG,
 :HV-CREATED-DATE, :HV-CREATED-BY)

Commit Point: Marked for batch commit

Step 7: Policy Usage Update (Section 4170-UPDATE-POLICY-USAGE, Lines 2761-2805)

Database Update (Lines 2774-2785):

UPDATE POLICY_TABLE
SET DEDUCTIBLE_MET = DEDUCTIBLE_MET + :WS-DEDUCTIBLE-APPLIED,
    OUT_OF_POCKET_MET = OUT_OF_POCKET_MET + :WS-PATIENT-PAYS,
    CLAIMS_COUNT = CLAIMS_COUNT + 1,
    LAST_CLAIM_DATE = CURRENT_DATE,
    LAST_UPDATE_DATE = CURRENT_TIMESTAMP,
    UPDATED_BY = :WS-PROGRAM-NAME
WHERE POLICY_NUMBER = :CLM-POLICY-NUMBER

High Fraud Customer Update (Lines 2790-2805):

IF Fraud Score >= 70 THEN
    UPDATE CUSTOMER_TABLE
    SET RISK_PROFILE = 'HIGH',
        FRAUD_ALERT_FLAG = 'Y',
        LAST_UPDATE_DATE = CURRENT_TIMESTAMP,
        UPDATED_BY = :WS-PROGRAM-NAME
    WHERE CUSTOMER_NUMBER = :CLM-CUSTOMER-NUMBER
END IF

Purpose:

  • Tracks policy usage for subsequent claims
  • Updates customer risk profile if fraud detected
  • Maintains accurate deductible and OOP amounts

Commit Point: Same transaction as claim insert; both commit together

Step 8: Output Generation (Section 4180-WRITE-CLAIM-OUTPUT, Lines 2811-2846)

CLMOUT File Record (Lines 2815-2825):

Transaction Type: 'CLAIM'
Claim ID: Generated 10-digit number
Claim Number: Business claim reference (15 characters)
Policy Number: 15-digit policy ID
Insurance Payment Amount: Calculated amount
Patient Responsibility: Calculated amount
Claim Status: PROCESSING, UNDER REVIEW, AUTO-APPROVED, etc.
Processing Timestamp: Current date/time

Special Outputs:

  • If fraud score >= 70: Status includes "FRAUD INVESTIGATION"
  • If fraud score 50-69: Status includes "MANUAL REVIEW"
  • If amount > $5,000: Status includes "PENDING APPROVAL"

Counters Updated:

  • WS-CLM-PROCESS-COUNT
  • WS-TOTAL-PROCESS-COUNT
  • WS-COMMIT-COUNT

Transaction Boundaries

Single Transaction Scope:

  1. Claim record INSERT
  2. Policy usage UPDATE
  3. (Optional) Customer risk UPDATE

All operations commit together. If any fails, all rollback.

Commit Frequency: Every 500 successful claim operations


Batch Processing Flow

The INSMASTR program implements a sophisticated batch processing architecture that handles multiple input file types, manages transaction commits, and generates comprehensive processing reports.

Batch Processing Sequence

Loading diagram...

Processing Mode Control

Mode Determination (Lines 847-879):

The program accepts a processing mode parameter via SYSIN:

ACCEPT WS-PROCESSING-MODE FROM SYSIN

EVALUATE TRUE
    WHEN PROCESS-POLICIES-ONLY (Mode = 'POLICY')
        PERFORM 2000-PROCESS-POLICIES

    WHEN PROCESS-RENEWALS-ONLY (Mode = 'RENEWAL')
        PERFORM 3000-PROCESS-RENEWALS

    WHEN PROCESS-CLAIMS-ONLY (Mode = 'CLAIM')
        PERFORM 4000-PROCESS-CLAIMS

    WHEN PROCESS-ALL-FILES (Mode = 'ALL')
        PERFORM 2000-PROCESS-POLICIES
        PERFORM 3000-PROCESS-RENEWALS
        PERFORM 4000-PROCESS-CLAIMS

    WHEN OTHER
        Display 'INVALID PROCESSING MODE'
        Return Code = 8
END-EVALUATE

Use Cases:

  • 'POLICY': Process only new policy applications (daily batch)
  • 'RENEWAL': Process only policy renewals (monthly batch)
  • 'CLAIM': Process only claims (multiple times daily)
  • 'ALL': Process all file types in sequence (comprehensive batch)

File Processing Loop Pattern

Each file type follows the same processing pattern:

Generic Loop Structure (applies to all three file types):

SET EOF-FLAG TO FALSE
PERFORM UNTIL EOF-FLAG = 'Y'
    READ INPUT-FILE INTO WORK-AREA
    EVALUATE FILE-STATUS
        WHEN '00'
            ADD 1 TO READ-COUNT
            IF DETAIL-RECORD
                PERFORM PROCESS-RECORD-SECTION
            END-IF
        WHEN '10'
            SET EOF-FLAG TO TRUE
        WHEN OTHER
            PERFORM 8000-ERROR-HANDLER
    END-EVALUATE

    IF COMMIT-COUNT >= COMMIT-FREQUENCY
        PERFORM 7000-COMMIT-WORK
    END-IF
END-PERFORM

Key Characteristics:

  • Sequential record processing (no random access)
  • Header and trailer records skipped
  • File status checked after every read
  • Commit threshold checked after every record
  • EOF gracefully handled
  • Errors don't stop file processing

Commit Strategy

Threshold-Based Commits (Lines 2852-2867):

7000-COMMIT-WORK SECTION.
    IF WS-COMMIT-COUNT > 0 THEN
        EXEC SQL
            COMMIT WORK
        END-EXEC

        IF SQLCODE = 0 THEN
            MOVE ZERO TO WS-COMMIT-COUNT
            DISPLAY 'COMMIT PERFORMED - RECORDS COMMITTED: '
                    WS-COMMIT-COUNT
        ELSE
            PERFORM 8000-ERROR-HANDLER
        END-IF
    END-IF.

Commit Counter Management:

After each successful database INSERT/UPDATE/MERGE:
    WS-COMMIT-COUNT = WS-COMMIT-COUNT + 1

After COMMIT:
    WS-COMMIT-COUNT = 0 (reset)

After ROLLBACK (error condition):
    WS-COMMIT-COUNT = 0 (reset)

Commit Frequency Configuration:

  • Default: Every 500 records (WS-COMMIT-FREQUENCY)
  • Configurable via constant change (Line 220)
  • Balance between:
    • Performance: Fewer commits = faster processing
    • Recovery: More frequent commits = less work lost on failure
    • Log Space: Larger commits = larger transaction logs

Error Recovery During Batch

Error Handling Philosophy:

  1. Record-Level Isolation: One bad record doesn't fail the batch
  2. Automatic Rollback: Database errors roll back uncommitted work
  3. Continuous Processing: Error logged, next record processed
  4. Comprehensive Logging: All errors written to ERRFILE
  5. Final Reporting: Summary shows success/error counts

Error Flow:

Record Processing Error
    ↓
Set ERROR-OCCURRED Flag
    ↓
Determine Severity (CRITICAL/SEVERE/WARNING)
    ↓
Format Error Record
    ↓
Write to ERRFILE
    ↓
Display on Console
    ↓
If SQL Error: ROLLBACK uncommitted work
    ↓
If CRITICAL: Abort program (9999-ABORT-PROGRAM)
    ↓
Otherwise: Continue to next record

Error Handling Data Flows

Error handling in INSMASTR follows a centralized pattern with severity-based routing and comprehensive error capture.

Error Handling Architecture

Loading diagram...

Error Categories and Codes

Critical Errors (1101-1999) - Program Termination:

  • 1101: Policy input file open failure
  • 1102: Renewal input file open failure
  • 1103: Claims input file open failure
  • 1104: Output file open failure
  • 1105: Error file open failure
  • 1201: DB2 connection failure
  • 1202: DB2 disconnection failure

Severe Errors (2001-4999) - Record Rejection, Continue Processing:

Policy Processing (2001-2999):

  • 2001: Invalid policy input data
  • 2002: Duplicate active policy found
  • 2003: Customer validation failure
  • 2004: Age out of range (< 18 or > 85)
  • 2005: Invalid insurance type
  • 2006: Coverage amount exceeds maximum
  • 2007: Risk score calculation failure
  • 2008: Premium calculation failure
  • 2009: Customer merge failure (SQL error)
  • 2010: Policy insert failure (SQL error)

Renewal Processing (3001-3999):

  • 3001: Invalid renewal input data
  • 3002: Policy not found
  • 3003: Policy not active
  • 3004: Invalid renewal term
  • 3005: Renewal premium calculation failure
  • 3006: New policy insert failure
  • 3007: Old policy update failure

Claims Processing (4001-4999):

  • 4001: Invalid claim input data
  • 4002: Policy not found
  • 4003: Policy inactive
  • 4004: Incident date out of policy period
  • 4005: Duplicate claim number
  • 4006: Fraud detection query failure
  • 4007: Payment calculation failure
  • 4008: Claim insert failure
  • 4009: Policy usage update failure
  • 4010: Provider not found

Warning Errors (Other Codes) - Logged for Review:

  • Non-fatal issues that don't prevent processing
  • Logged but don't increment error counters

Error Record Format

ERRFILE Record Layout (250 bytes):

ERROR | [Code] | [Severity] | [Message] | SQLCODE=[code] | [Timestamp]

Example Error Records:

ERROR|2004|SEVERE|CUSTOMER AGE OUT OF RANGE: 17|SQLCODE=0|2024-01-15-14.30.25.123456
ERROR|2010|SEVERE|POLICY INSERT FAILED|SQLCODE=-803|2024-01-15-14.30.26.456789
ERROR|3002|SEVERE|POLICY NOT FOUND FOR RENEWAL|SQLCODE=+100|2024-01-15-14.30.27.789012
ERROR|4006|SEVERE|FRAUD DETECTION QUERY FAILED|SQLCODE=-911|2024-01-15-14.30.28.012345

SQL Error Handling

SQLCODE Interpretation:

  • 0: Success (no error)
  • +100: No rows found (acceptable in some contexts)
  • Negative: Error condition requiring rollback

Common SQL Errors:

  • -803: Duplicate key (trying to insert duplicate policy/claim)
  • -904: Resource unavailable
  • -911: Deadlock or timeout
  • -913: Deadlock detected
  • -922: Connection lost

Rollback Trigger (Lines 2928-2933):

IF SQLCODE NOT = 0 AND SQLCODE NOT = 100 THEN
    EXEC SQL
        ROLLBACK WORK
    END-EXEC
    MOVE ZERO TO WS-COMMIT-COUNT
END-IF

Impact of Rollback:

  • All uncommitted database operations reversed
  • Commit counter reset to zero
  • Processing continues with next record
  • Last committed state is safe recovery point

Console Error Display

Error Console Output (Lines 2917-2923):

DISPLAY '***ERROR*** CODE: ' WS-ERROR-CODE
DISPLAY '            SEVERITY: ' WS-ERROR-SEVERITY
DISPLAY '            MESSAGE: ' WS-ERROR-MESSAGE
DISPLAY '            SQLCODE: ' SQLCODE
DISPLAY '            SQLERRMC: ' SQLERRMC

Purpose:

  • Real-time error notification to operators
  • JCL SYSOUT captures for job log
  • Debugging aid during development/testing
  • Operational monitoring during production runs

Program Termination Scenarios

Normal Termination (Return Code 0 or 4):

  • All files processed
  • Final commit executed
  • Summary report written
  • Files closed
  • DB2 disconnected
  • GOBACK executed

Abnormal Termination (Return Code 16):

  • Critical error encountered
  • Abend report written
  • Current transaction rolled back
  • Files closed (if possible)
  • DB2 disconnected (if possible)
  • Program terminates via 9999-ABORT-PROGRAM

Transaction Boundaries

Transaction boundaries define the scope of atomic database operations, ensuring data consistency and enabling recovery from failures.

Transaction Scope Definitions

Transaction 1: Policy Creation

BEGIN (implicit after last commit or program start)
    ↓
MERGE INTO CUSTOMER_TABLE (customer record)
    ↓
INSERT INTO POLICY_TABLE (policy record)
    ↓
COMMIT (explicit at 500-record threshold or program end)

Atomicity: Customer and policy inserted together or not at all.

Transaction 2: Policy Renewal

BEGIN (implicit)
    ↓
INSERT INTO POLICY_TABLE (new policy record)
    ↓
UPDATE POLICY_TABLE (old policy status = RENEWED)
    ↓
COMMIT (explicit at threshold or program end)

Atomicity: New policy and old policy update occur together.

Transaction 3: Claim Processing

BEGIN (implicit)
    ↓
INSERT INTO CLAIM_TABLE (claim record)
    ↓
UPDATE POLICY_TABLE (deductible met, OOP met, claims count)
    ↓
[Optional] UPDATE CUSTOMER_TABLE (risk profile if fraud detected)
    ↓
COMMIT (explicit at threshold or program end)

Atomicity: Claim and policy usage update occur together.

Commit Point Analysis

Explicit Commit Locations:

  1. 7000-COMMIT-WORK Section (Lines 2852-2867)

    • Called when WS-COMMIT-COUNT >= 500
    • Resets counter to zero on success
    • Invoked from: Policy loop, Renewal loop, Claims loop
  2. 9000-FINALIZE-PROGRAM Section (Lines 2947-3228)

    • Final commit for any pending operations
    • Called before program termination
    • Lines 2951-2953: Final commit execution

Implicit Transaction Boundaries:

  • Start: After CONNECT TO INSPROD (1200-CONNECT-DB2)
  • Start: After each COMMIT WORK execution
  • End: At each COMMIT WORK execution
  • End: At ROLLBACK WORK (error condition)
  • End: At DISCONNECT (program termination)

Rollback Scenarios

Automatic Rollback Triggers:

  1. SQL Error During Processing (Lines 2928-2933):
IF SQLCODE NOT = 0 AND SQLCODE NOT = 100
    EXEC SQL ROLLBACK WORK END-EXEC
    MOVE ZERO TO WS-COMMIT-COUNT
  1. Program Abend (9999-ABORT-PROGRAM):
EXEC SQL ROLLBACK WORK END-EXEC
DISPLAY 'TRANSACTION ROLLED BACK DUE TO ABEND'

Rollback Impact:

  • All database operations since last commit are undone
  • Database returns to last committed state
  • File outputs (POLOUT, RENOUT, CLMOUT) are NOT rolled back
  • Error files (ERRFILE) are NOT rolled back
  • In-memory counters remain (showing attempted vs. committed counts)

Recovery Strategy:

  • Corrected records can be resubmitted in subsequent run
  • Error file analysis identifies problem records
  • Database integrity maintained through rollback
  • Committed records remain valid

Isolation Level Impact

Cursor Stability (CS) Configuration (Lines 1043-1049):

EXEC SQL
    CONNECT TO INSPROD USER :WS-PROGRAM-NAME
    USING 'INSPROD'
END-EXEC

Isolation Level: CS (Cursor Stability)
Lock Timeout: 30 seconds

CS Isolation Characteristics:

  • Read Locks: Released immediately after row is read
  • Write Locks: Held until commit or rollback
  • Phantom Reads: Possible (other transactions can insert matching rows)
  • Dirty Reads: Prevented (can't read uncommitted data)
  • Repeatable Reads: Not guaranteed (rows can be updated by others)

Implications for INSMASTR:

  1. Duplicate Checks: Multiple simultaneous runs could potentially create duplicates if checking/inserting same policy between commits
  2. Fraud Analysis: Query results reflect committed data only
  3. Performance: Better concurrency than RR (Repeatable Read) isolation
  4. Lock Timeout: 30-second wait prevents indefinite hangs

Concurrency Considerations:

  • Multiple batch jobs can run simultaneously
  • Each operates on different input files
  • Shared database access requires lock management
  • Commit frequency (500 records) limits lock duration

Database Commit Strategy

The commit strategy balances three competing objectives: performance, data integrity, and recovery capability.

Commit Frequency Rationale

500-Record Threshold (WS-COMMIT-FREQUENCY = 500):

Advantages:

  • Performance: Reduces commit overhead (fewer I/O operations)
  • Log Management: Reasonable transaction log size
  • Lock Duration: Moderate lock holding time
  • Throughput: Good balance for typical workloads

Disadvantages:

  • Recovery Window: Up to 500 records lost on failure
  • Lock Contention: Longer lock holding than smaller batches
  • Memory: Larger transaction buffer requirements

Alternative Configurations:

Small Batch (100 records):
    + Faster recovery
    + Lower memory
    - More commit overhead
    - Reduced throughput

Large Batch (1000 records):
    + Higher throughput
    + Less commit overhead
    - Longer recovery time
    - Higher lock contention

Transaction Log Management

DB2 Transaction Log Considerations:

Before Image (UNDO) Logging:

  • Records original values before update
  • Enables ROLLBACK functionality
  • Space required: Proportional to uncommitted changes

After Image (REDO) Logging:

  • Records new values after update
  • Enables crash recovery
  • Space required: Proportional to committed changes

Log Space Calculation (approximate):

Single Policy Insert: ~500 bytes
Single Claim Insert: ~600 bytes
Single Update: ~200 bytes

500-Record Policy Batch:
    500 × (CUSTOMER_MERGE + POLICY_INSERT)
    ≈ 500 × (500 + 500) = 500 KB per commit

500-Record Claim Batch:
    500 × (CLAIM_INSERT + POLICY_UPDATE)
    ≈ 500 × (600 + 200) = 400 KB per commit

Log Space Monitoring:

  • DBA should monitor active log usage
  • Adjust WS-COMMIT-FREQUENCY if log space issues
  • Consider log archival frequency

Multi-File Processing Commit Strategy

Sequential File Processing (Mode = 'ALL'):

Process Policy File:
    Read all policy records
    Commit every 500 records
    Final commit at end of file

Process Renewal File:
    Read all renewal records
    Commit every 500 records (separate counter continues)
    Final commit at end of file

Process Claims File:
    Read all claims records
    Commit every 500 records
    Final commit at end of file

Key Point: Commit counter is CONTINUOUS across file types, not reset between files.

Example Scenario:

Policy File: 400 records processed
    - No commit yet (counter = 400)

Renewal File: 150 records processed
    - Commit triggered at record 100 (counter = 500)
    - Counter reset to 0
    - Counter now = 50 after 150 renewals processed

Claims File: 500 records processed
    - Commit triggered at record 450 (counter = 500)
    - Counter reset to 0
    - Commit triggered at record 500 (counter = 500)
    - Counter reset to 0

Recovery Point Objectives

Recovery Point Objective (RPO): Maximum acceptable data loss

Current Configuration:

  • RPO: Up to 500 records (last commit point)
  • Recovery Time Objective (RTO): Rerun from last successful commit

Recovery Procedure:

  1. Identify last successful commit in job log
  2. Determine records processed since last commit (from counters)
  3. Recreate input files excluding committed records
  4. Rerun program with corrected input
  5. Database automatically at correct state (prior commits retained)

Audit Trail Support:

  • All database records include CREATED_DATE and CREATED_BY
  • Summary report shows total processed vs. committed
  • Error file shows rejected records
  • Output files show successful records

Example Recovery:

Job Log Shows:
    - Policies Processed: 1500
    - Policies Committed: 1500 (3 commits of 500 each)
    - Renewals Processed: 750
    - Renewals Committed: 500 (1 commit)
    - Claims Processed: 200
    - Database Error at Claim #200
    - Rollback Executed

Recovery Action:
    - Policies: Fully committed (no action)
    - Renewals: 500 committed, 250 pending (resubmit last 250)
    - Claims: None committed (resubmit all 200 after error correction)

Commit Verification

Post-Commit Verification (Lines 2856-2864):

EXEC SQL
    COMMIT WORK
END-EXEC

IF SQLCODE = 0 THEN
    MOVE ZERO TO WS-COMMIT-COUNT
    DISPLAY 'COMMIT PERFORMED - RECORDS COMMITTED: '
            WS-COMMIT-COUNT
ELSE
    PERFORM 8000-ERROR-HANDLER
    (Error handler will execute ROLLBACK)
END-IF

Commit Failure Handling:

  • SQLCODE checked after every commit
  • Non-zero SQLCODE triggers error handler
  • Automatic rollback attempted
  • Program may terminate if commit repeatedly fails

Monitoring Points:

  • Console displays confirm successful commits
  • Commit count tracked throughout execution
  • Final summary report shows total commits
  • Job log captures all commit messages

Was this page helpful?