Record Locks and Commitment Control in RPGLE Programs

This page covers record locking and commitment control from inside an RPGLE program: how CHAIN and the read operations lock a record on an update file, the N extender that skips the lock, what happens when a lock wait times out, and the COMMIT and ROLBK opcodes once a file is opened under commitment control. It does not cover the CL side — starting commitment control with STRCMTCTL, journaling prerequisites, or ending it with ENDCMTCTL. For that, see IBM i Commitment Control and Transaction Management.

All examples are free-form RPGLE and are IBM DOC CHECKED or STATIC CHECKED against IBM’s RPG and Database documentation; none has been compiled or run on an IBM i system in this workspace.

How RPG locks a record

IBM’s record-locking rule for RPG IV is a mode decided at read time, not a separate keyword: a record read from a file opened with USAGE(*UPDATE) is read for update by default, and reading it for update places a lock. Other file usages read for inquiry only and place no lock.

dcl-f orderFile usage(*update) keyed;

dcl-s orderNo char(10) inz('ORD0012345');

chain orderNo orderFile;
if %found;
  // the record is now locked for update
  orderQty -= 1;
  update orderRecord;
endif;

IBM DOC CHECKED (Record Locking, IBM i Database Programming). Because the lock comes from the combination of USAGE(*UPDATE) and a plain update-capable read, there is no separate “lock this record” keyword to code — the brief term sometimes used for this, “UPDLCK”, does not appear in IBM’s RPG documentation. The mechanism is the default update-read lock described above, together with the N extender below for the opposite case.

Skipping the lock with the N extender

To read a record from an update-capable file without locking it, add the N extender to CHAIN, READ, READE, READP or READPE.

dcl-f orderFile usage(*update) keyed;

chain(n) orderNo orderFile;   // read for inquiry, no lock placed
if %found;
  // safe to display; cannot UPDATE or DELETE this read without re-reading for update
endif;

IBM DOC CHECKED. A record read with (N) cannot be the target of UPDATE or DELETE without re-reading it for update first; the extender is for inspection, not for a read-then-change sequence.

What releases a lock

IBM lists these as the events that release an RPG record lock on a file: the record is updated or deleted, another record is read from the file, a SETLL or SETGT repositions the file, an explicit UNLOCK is issued, or an output operation with no field names is performed (an OUTPUT-style write with no named fields; adding a new record does not release an existing lock).

chain orderNo orderFile;
if %found;
  // ... decide not to change it after all
  unlock orderFile;
endif;

IBM DOC CHECKED.

WAITRCD and the lock-wait timeout

WAITRCD is not an RPG source keyword; it is a file attribute set with CRTPF, CHGPF or an OVRDBF override, and it controls how long a program waits for a lock another job is holding before RPG raises an error. IBM documents the resulting runtime status as 1218, and the default unhandled behaviour is the RNQ1218 inquiry message offering a retry — which is a problem inside a subprocedure, because subprocedures do not receive that inquiry.

OVRDBF FILE(ORDFILE) WAITRCD(5)
dcl-f orderFile usage(*update) keyed;

monitor;
  chain orderNo orderFile;
on-error 1218;
  // the record was locked by another job past the WAITRCD limit
  dsply 'Order locked by another user, try again';
endmon;

IBM DOC CHECKED (Record Locking, IBM i Database Programming, for status 1218 and the WAITRCD wait). Checking for status 1218 with MONITOR/ON-ERROR, or the E extender with %STATUS, is the documented way to handle a lock-wait timeout inside a subprocedure, since the default inquiry message is not an option there.

COMMIT: opening a file under commitment control

Putting a file under commitment control from RPG is a file-level keyword, COMMIT, not a control-specification setting. IBM documents COMMIT‘s optional parameter as an indicator name that RPG implicitly defines as a one-character indicator field initialized to '0'; the file opens with commitment control on only if that indicator contains '1' at open time, and the indicator must be set before the file is opened — for a program-initialization open, that means passing it as a call parameter or defining it as an external indicator; for an explicit OPEN, setting it beforehand in the program.

dcl-s cmtOn ind inz('1');

dcl-f orderFile usage(*update: *delete) keyed commit(cmtOn);

IBM DOC CHECKED (COMMIT file-description keyword). cmtOn is initialized to '1' before the implicit open at program start, so orderFile opens under commitment control. STRCMTCTL must already have started commitment control at the job level, and every file coded with COMMIT must be journaled — both are CL-side prerequisites covered in the linked commitment-control article, not something the COMMIT file keyword does on its own.

COMMIT and ROLBK opcodes

Once one or more files are open under commitment control, the COMMIT and ROLBK opcodes close out the current unit of work.

dcl-s cmtOn ind inz('1');

dcl-f orderHdr usage(*update: *delete) keyed commit(cmtOn);
dcl-f orderLin usage(*update: *delete: *add) keyed commit(cmtOn);

dcl-s orderNo char(10) inz('ORD0012345');
dcl-s updated ind inz(*off);

monitor;
  chain orderNo orderHdr;
  if %found;
    hdrStatus = 'P';
    update orderHdrRecord;
    updated = *on;
  endif;

  if updated;
    chain orderNo orderLin;
    dou not %eof(orderLin);
      lineQty -= 1;
      update orderLinRecord;
      reade orderNo orderLin;
    enddo;
  endif;
on-error;
  updated = *off;
endmon;

if updated;
  commit;
else;
  rolbk;
endif;

STATIC CHECKED against the IBM-documented COMMIT and ROLBK opcode syntax (both take an optional operation extender (E) or an ER error indicator — not both — for program status codes 802–805; neither takes a factor 1 or result field). COMMIT applies every output change made since the last COMMIT or ROLBK to every commitment-controlled file in scope (not only the files this program itself has open — IBM documents the scope as the activation group or job, set by STRCMTCTL‘s commit scope) and releases every record lock those files hold. ROLBK instead discards those changes, releases the same locks, and repositions each file to where it was at the previous commit point (or at open, if there was no previous commit).

// Free-form opcode forms
commit;        // or: commit(e);
rolbk;         // or: rolbk(e);

IBM DOC CHECKED (COMMIT and ROLBK opcodes, ILE RPG Reference).

Locking under commitment control

IBM documents an exception to the plain-RPG lock model once commitment control is active: lock duration and release timing can differ from the uncommitted case described earlier in this page, governed by the lock level (*CHG, *CS, *ALL) chosen on STRCMTCTL. The detail of each lock level is a CL/STRCMTCTL concern, covered in IBM i Commitment Control and Transaction Management; from the RPG side, the practical point is that COMMIT and ROLBK are what release those locks at the end of a unit of work, not the ordinary release events listed earlier in this page (update, delete, a new read, SETLL/SETGT, or UNLOCK), which still apply but do not end the unit of work itself.

Common mistakes

  • Looking for an “UPDLCK” keyword. There isn’t one; the lock comes from reading an update-capable file without the N extender.
  • Reading with (N) and then issuing UPDATE or DELETE against that read without re-reading the record for update first.
  • Assuming WAITRCD is set in the RPG source. It is a file attribute, changed with CRTPF, CHGPF or OVRDBF, not an F-spec or DCL-F keyword.
  • Letting the default RNQ1218 inquiry message reach a subprocedure, where it cannot be answered interactively. Check status 1218 explicitly instead.
  • Coding COMMIT(cmtOn) on the file without STRCMTCTL already active at the job level, or without the file journaled — the COMMIT file keyword only requests commitment control at open time, it does not start commitment control itself.
  • Assuming COMMIT only affects files this program itself declared. IBM documents it as committing every commitment-controlled file in the job or activation group, per the commit scope chosen on STRCMTCTL.

FAQ

Does CHAIN always lock the record it reads?

Only when the file is opened USAGE(*UPDATE) and the read has no N extender. A file not opened for update, or a read with (N), does not lock the record.

What is the difference between UNLOCK and ROLBK for releasing a lock?

UNLOCK releases the lock on one record in one file, without affecting any pending output changes. ROLBK discards every uncommitted change and releases every lock across every commitment-controlled file in the unit of work’s scope.

Can I use COMMIT and ROLBK without STRCMTCTL?

No. IBM documents an error if commitment control is not active when COMMIT or ROLBK runs. STRCMTCTL (CL side) must start commitment control, and the files must be journaled and opened with the COMMIT file keyword, before these opcodes do anything.

Summary

  • RPG locks a record by reading it for update from a file opened USAGE(*UPDATE); the N extender on CHAIN/READ/READE/READP/READPE skips the lock.
  • WAITRCD (a file attribute, not an RPG keyword) controls the lock-wait timeout; a timeout surfaces as status 1218, checked with MONITOR/ON-ERROR or the E extender.
  • The COMMIT file-description keyword, with an indicator set to '1' before open, requests commitment control for that file — but STRCMTCTL and journaling must already be in place.
  • COMMIT and ROLBK close a unit of work: COMMIT applies every change and releases every lock in scope; ROLBK discards the changes, releases the locks, and repositions each file to its last commit point.
  • The CL-side setup — STRCMTCTL, journaling, savepoints and multi-file patterns — is covered in IBM i Commitment Control and Transaction Management.

Sources: Record Locking, IBM i Database Programming, File Locking, COMMIT (Commit) opcode, ILE RPG Reference, ROLBK (Roll Back) opcode, ILE RPG Reference, COMMIT file-description keyword, Using Commitment Control.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top