Adabas developer on retainer: Natural CLMBTCH1 READ CLAIMREC HOLD accumulates 847 Hold Queue entries without END TRANSACTION on validation escape

Software AG Adabas • Natural 6.3 • z/OS 2.4 • Adabas 8.4 • Hold Queue • response code 145 • retainer billing

At Northeast Regional Insurance Group, the nightly claims validation batch job had been running fine for years. Then the insurance carrier grew from 120,000 to 340,000 policies in eighteen months and the nightly CLMVALJB job started taking 2 hours 34 minutes instead of 38 minutes. That alone was manageable. What wasn’t manageable: the 23 claims adjusters who came in at 8 AM and immediately got Adabas response code 145 RECORD CURRENTLY HELD BY ANOTHER USER every time they tried to open a claim for update. Their morning productivity was zero while the batch job finished.

The carrier had been on Software AG Adabas 8.4 on z/OS 2.4 since 2009. The Natural 6.3 programs were stable. The retainer consultant they brought in had worked with Adabas/Natural since Adabas 5 and recognized the Hold Queue symptom within minutes of getting AOS access.

The CLMBTCH1 program and the READ HOLD loop

CLMBTCH1 is the claims batch validation program in Natural library CLMLIB. Its job: read every pending claim record from Adabas file 15 (CLAIMREC), validate that CLAIM-AMOUNT does not exceed the policyholder’s COVERAGE-LIMIT, and mark valid claims as STATUS = ‘V’ for downstream processing. The file had grown to 182,300 records as policy count tripled.

The relevant Natural source looked like this:

DEFINE DATA LOCAL
  1 CLAIMREC VIEW OF CLAIMREC
    2 ISN
    2 CLAIM-DATE      (D)
    2 CLAIM-AMOUNT    (N9.2)
    2 COVERAGE-LIMIT  (N9.2)
    2 STATUS          (A1)
END-DEFINE
*
READ CLAIMREC BY CLAIM-DATE HOLD         /* HOLD = exclusive lock per ISN */
  IF CLAIM-AMOUNT > COVERAGE-LIMIT
    ESCAPE BOTTOM                        /* exits loop — HOLD not released */
  END-IF
  IF STATUS NE 'P'
    ESCAPE BOTTOM                        /* exits loop — HOLD not released */
  END-IF
  STATUS := 'V'
  UPDATE CLAIMREC                        /* releases HOLD via ET on next commit */
  END TRANSACTION
END-READ

The problem is the two ESCAPE BOTTOM branches. In Adabas Natural, READ ... HOLD places each record’s ISN (Internal Sequence Number) into the Adabas Hold Queue the moment it is read. The Hold is released in three ways: an END TRANSACTION (commit), a BACKOUT TRANSACTION (rollback), or an explicit RELEASE statement. ESCAPE BOTTOM exits the READ loop entirely — it is a control-flow jump, not a database operation. It releases nothing.

When CLAIM-AMOUNT exceeded COVERAGE-LIMIT or STATUS was already non-pending, the program escaped the loop, leaving that ISN’s Hold in the Adabas Hold Queue. As the job processed 182,300 records, it issued END TRANSACTION only for the records it actually updated. The 847 validation-failure records accumulated in the Hold Queue throughout the 2h 34m run, never released.

AOS diagnosis: Hold Queue 847 ISNs in file 15

The retainer consultant connected to Adabas Online Services (AOS) while CLMVALJB was running. AOS → Active Users → user CLMBATCH → program CLMBTCH1 showed a Hold Queue count that was climbing steadily: 312 ISNs, then 489, then 714. By the time the job completed, AOS showed 847 ISNs in Hold Queue for file 15 (CLAIMREC).

ADANIS (Adabas Nucleus Information System) confirmed: HQ ENTRIES = 847 for database INSURANCE DBID 183. Every one of those 847 ISNs was exclusively held by user session CLMBATCH. Any other Natural user issuing READ CLAIMREC BY ... HOLD for one of those 847 ISNs would immediately receive Adabas response code 145: RECORD CURRENTLY HELD BY ANOTHER USER.

The 23 claims adjusters running Natural online program CLMONL01 (Claims Online Maintenance) all started work by reading claims records with HOLD to prepare for update. Whichever of the 847 held ISNs they tried to open: response code 145, no retry logic, hard error displayed to user. The morning shift was effectively locked out of a quarter of the active claims portfolio until CLMVALJB ended and its Hold Queue was cleared by job termination.

The immediate operational workaround was an operator ADAEND STTKN=183 forced termination of the CLMBTCH1 user session, which released all 847 Holds instantly. That freed the adjusters but forced a full restart of the validation job that night.

Fix: BACKOUT TRANSACTION before ESCAPE BOTTOM

The fix required three changes to CLMBTCH1:

READ CLAIMREC BY CLAIM-DATE HOLD
  IF CLAIM-AMOUNT > COVERAGE-LIMIT
    BACKOUT TRANSACTION                  /* releases HOLD on current ISN */
    ESCAPE BOTTOM
  END-IF
  IF STATUS NE 'P'
    BACKOUT TRANSACTION                  /* releases HOLD on current ISN */
    ESCAPE BOTTOM
  END-IF
  STATUS := 'V'
  UPDATE CLAIMREC
  END TRANSACTION
END-READ

BACKOUT TRANSACTION rolls back any pending database changes and releases all ISNs in the current transaction’s Hold Queue. Since only one record was ever in flight at a time in this loop (the current READ result), BACKOUT releases exactly that one Hold before the ESCAPE. Hold Queue during processing: 847 → 0 concurrently held at any moment.

A deeper restructuring was also applied: the validation pass was separated from the update pass. The first pass uses READ CLAIMREC BY CLAIM-DATE (no HOLD) to collect the ISNs of valid claims into a Natural internal array. The second pass reads only those ISNs READ CLAIMREC ISN HOLD and immediately calls UPDATE. This eliminated the Hold Window for the validation path entirely. Job runtime also improved from 2h 34m to 1h 47m because READ ... HOLD is measurably slower than READ alone when the Hold Queue is large.

How HourTab helps Adabas retainer consultants

The carrier’s operations team initially estimated the morning outage at “a couple of hours.” The retainer consultant’s actual work was: 1.0h AOS diagnosis (Hold Queue identification, ADANIS confirmation, active user trace); 1.5h Natural source fix (BACKOUT TRANSACTION placement, two-pass restructuring, CLMLIB recompile); 1.0h batch regression test (CLMVALJB test run on 5,000-record subset, AOS Hold Queue monitoring during run, adjusters smoke test on CLMONL01). Total: 3.5 hours. The carrier’s procurement team asked for a breakdown; the retainer consultant sent them a HourTab link and the question was answered before the second email arrived.

HourTab turns a time-tracker CSV into a public retainer-hours URL your client can bookmark — no login, no portal, no “how many hours do I have left?” emails. Free for one retainer. $9/mo for up to ten.

FAQ: Adabas developer retainers

What does a Software AG Adabas developer on retainer typically do?

A Software AG Adabas developer on monthly retainer covers Natural application program maintenance (READ HOLD for update-mode record access, END TRANSACTION for commit and Hold Queue release, BACKOUT TRANSACTION for rollback and Hold Queue release, FIND for set-oriented retrieval, STORE for record insertion, DELETE for removal, UPDATE for in-place modification, ESCAPE BOTTOM/TOP for structured loop exit), Adabas file and field definition maintenance via Adabas Data Dictionary (PREDICT), Adabas Online Services (AOS) administration (Active Users, Hold Queue inspection, Nucleus Statistics, File Directory), Adabas response code diagnosis (code 145 record held by another user, code 3 end of file, code 64 ISN not found), Natural batch program (CMSYNIN SYSIN DD) and online program (Natural Security, LOGON, LOGOFF) maintenance, Natural error handling (ON ERROR PERFORM, ESCAPE ROUTINE, *ERROR variable), and Adabas buffer pool, Work pool, and FORMAT/HOLD block tuning.

What Adabas debugging work is most commonly underlogged?

Natural batch programs that READ HOLD inside a loop without END TRANSACTION or BACKOUT TRANSACTION on validation-failure escape paths are the most systematically underlogged Adabas retainer work. Pattern: CLMBTCH1 Natural 6.3 batch, Adabas 8.4 z/OS 2.4; READ CLAIMREC BY CLAIM-DATE HOLD; FOR EACH CLAIMREC: IF CLAIM-AMOUNT > COVERAGE-LIMIT → ESCAPE BOTTOM (no BACKOUT TRANSACTION); 2h 34m run; 847 ESCAPE-triggered ISNs remain in Adabas Hold Queue for file 15 (CLAIMREC); AOS Active Users → CLMBTCH1 → Hold Queue: 847 ISNs; 23 online users READ CLAIMREC HOLD → Adabas response code 145 RECORD CURRENTLY HELD BY ANOTHER USER; ADANIS NUCLEUS INFORMATION: HQ ENTRIES = 847; fix: BACKOUT TRANSACTION before ESCAPE BOTTOM; also restructured to READ without HOLD for validation pass, re-READ WITH HOLD only before UPDATE. Log must name the Natural program, Adabas file number, READ HOLD loop structure, ESCAPE path, AOS Hold Queue count, and response code.

What are typical Software AG Adabas developer retainer rates?

Entry-level Adabas developers with Natural fixed-format source reading, basic AOS navigation, and READ/FIND/STORE/UPDATE/DELETE statement maintenance typically bill at $70 to $115 per hour. Mid-level Adabas developers with Natural structured programming (DECIDE FOR/ON, PERFORM subroutines, ESCAPE BOTTOM/TOP, ON ERROR PERFORM), Adabas Hold Queue diagnosis (AOS Active Users, response code 145 root cause, BACKOUT TRANSACTION placement), Adabas DDM (Data Definition Module) and PREDICT data dictionary maintenance, Natural Security administration (library protection, program-level security), and batch Natural CMSYNIN/CMPRINT JCL integration typically bill at $105 to $175 per hour. Senior Adabas developers with Adabas nucleus parameter tuning (LBP buffer pool, LWP Work pool, NAB, NH hold queue size), Natural ISPF editor and Natural Single Point of Development (SPoD) administration, Adabas Online Services extended administration (checkpoint datasets, ADAORD utility, ADACMP compression), Adabas 8 to 9 version upgrade support, and Natural 6 to Natural for zIIP migration typically bill at $155 to $260 per hour. Monthly retainer ranges: $2,800 to $5,800/month for Natural maintenance, Hold Queue diagnosis, and AOS administration; $5,200 to $10,500/month for active Adabas/Natural development, nucleus tuning, and version upgrade support.

What should a Software AG Adabas developer retainer agreement include?

An Adabas/Natural retainer agreement should specify: Adabas version (8.4, 8.5, 9.x) and Natural version (6.3, 8.x, 9.x) — PTF level and compatibility matrix are version-specific; whether the retainer covers Natural online programs (LOGON library, Natural Security), batch programs (CMSYNIN SYSIN DD card input), or both; which Adabas databases and file numbers are in scope (database ID, file 15 CLAIMREC, file 22 POLREC — file number determines DDM source and PREDICT entry); whether PREDICT data dictionary maintenance is in scope (field level definitions, reference fields, relationship files); whether Adabas nucleus administration is in scope (AOS, ADASAV backup/restore, ADAORD file reorder, ADACMP file compress); whether Natural Security library and user profile administration is in scope; whether Adabas response code root cause analysis (code 145 hold conflict, code 9 ISN beyond range, code 64 ISN not found) is in scope; and whether Adabas cluster services or Adabas for Linux/Unix/Windows (LUW) instances are in scope alongside the z/OS nucleus.

How should Adabas developer retainer hours be logged?

Log each Adabas retainer session with the Natural version, Adabas version, program name, file name, file number, operation, Hold Queue count, and before/after metric. For READ HOLD without END TRANSACTION: Natural 6.3 batch; Adabas 8.4 z/OS 2.4; database INSURANCE DBID 183; file 15 CLAIMREC; program CLMBTCH1 library CLMLIB; JCL job CLMVALJB user CLMBATCH; READ CLAIMREC BY CLAIM-DATE HOLD — each READ HOLD places ISN in Adabas Hold Queue; FOR EACH CLAIMREC: IF CLAIM-AMOUNT > COVERAGE-LIMIT → ESCAPE BOTTOM (no END TRANSACTION / no BACKOUT TRANSACTION — ISN stays in Hold Queue); 182,300 CLAIMREC reads, 847 ESCAPE-triggered without release; AOS ACTIVE USERS CLMBTCH1 HOLD QUEUE: 847 ISNs in file 15; ADANIS NUCLEUS: HQ ENTRIES 847; 23 online users program CLMONL01 READ CLAIMREC HOLD → Adabas 145 RECORD CURRENTLY HELD BY ANOTHER USER; ops workaround: operator ADAEND force-terminated CLMBTCH1 STTKN=183 — released all 847 HOLDs; fix: BACKOUT TRANSACTION before each ESCAPE BOTTOM on validation failure paths at source lines 47, 63, 81 of CLMBTCH1; also: READ CLAIMREC BY CLAIM-DATE (no HOLD) for validation pass; re-READ CLAIMREC ISN HOLD before UPDATE for update pass; Hold Queue during processing: 847 → 0; hours: 1h AOS diagnosis + 1.5h Natural source fix + 1h batch regression test.

See also: Natural language developer retainer · Db2 developer retainer · IMS DB developer retainer