Das mache ich:

Am einfachsten ist ein Service, klar mit eigener geschlüsselter Tabelle.
Die Tabelle enthält einen Hauptkey, ggf. Mandant, so wie ein allgemeines großes Feld (256 reicht meist) als Sperr-Key. Zusätzlich ein Feld mit dem Job-Bezeichner und aus statistischen Gründen einen Timestamp.
Der Service läuft in einer eigenen ACTGRP mit Commit *CHG.
Der Service liefert *on/*off ob eine Sperre erhalten wurde und per Referenz eine Error-Struktur, die den sperrenden Job bezeichnet. Somit kann per "if not GetLock(Mandant : %char(k1) + ',' + %char(k2) : error)" einfach geprüft werden.
Mittels UnLock(Mandant : %char(k1) + ',' + %char(k2)) wird der Lock entfernt, wenn er dem Job gehört.
k1 + k2 sind hier Synonyme für variable Schlüsselgestaltung.

Sperrschleife wegen konkurierender Zugriffe:
Step 1:
Read und prüfen per SQL ACTIVE_JOB_INFO
- Wenn nicht vorhanden, Insert mit Schlüssel eigenem Job und Timestamp
- Wenn SQLCODE = 0, commit und return *on
- Wenn doppelter Key, iter in Schleife, anderer war schneller, erforderliche falls anderer Rollback macht.
- Wenn SQLCODE <> 0, schwerer Fehler, der nicht vorkommen sollte, rollback, return *off
Step 2:
- wenn eigener Job oder Job nicht aktiv, update Timestamp, commit return *on
- wenn Job Aktiv, commit, return *off.

Im Test auf einer P9 konnte ich ca. 1000 Locks je Sekunde damit durchführen.
Wenn Programme über Menüs aufgerufen werden, kann man entweder im Menüprogramm oder per Wrapper nach Ende des Programmes einen RemoveAllLocks() des eigenen Jobs machen.

Aus Sicherheitsgründen erstelle ich noch einen Haupt-Lock um parallele Locks auszuschliessen:
do *on;
upddate locktable set locktime = current timestamp;
wenn sqlcode = 100 => Insert
wenn sqlcode = 0 => leave
// grober Fehler
enddo;

Somit kann noch sichergestellt werden, dass für die Lockprüfung keiner dazwischen kommt.

Jedes Programm ist selber dafür verantwortlich, Locks zu setzen und zu entfernen. Auf Grund der Schlüssel kann man beliebig viele Locks setzen.

1 Mal am Tag werden alle Locks gelöscht, deren Jobs nicht mehr aktiv sind.