LOCKs and ZTSTART and ZTCOMMIT transaction fences have an important relationship. MUPIP JOURNAL -RECOVER assumes that fenced transactions are isolated and never performs a cascading roll-back. The term cascading roll-back describes the situation that occurs when dropping one transaction causes previous transactions to be sequentially dropped, until potentially all transactions are dropped. If an application violates this assumption, a JOURNAL -RECOVER may create a database with application-level integrity problems. M LOCKs ensure the isolation of a sequence of updates from interaction with any other updates. TSTART and TCOMMIT transaction fences implicitly exhibit the required isolation whether fences are used with or without associated LOCKs.
Example of a non-isolated transaction:
Process A Process B
--------- ---------
ZTS
S ^(acct)=^AMT(d,acct)+amt
ZTS
S ^(acct)=^AMT(d,acct)+amt
S (j,^(0))=^JNL(acct,0)+1
S ^JNL(acct,j)=stf
ZTC
S (j,^(0))=^JNL(acct,0)+1
-- failure --
These two sets of transactions are not isolated from each other. After the system fails, Process A's transaction must be removed by a -RECOVER -BACKWARD or not replayed by a -RECOVER -FORWARD. However, if acct has the same value for both processes when Process B's transaction is recovered, ^AMT(d,acct) includes Process A's amt as well as Process B's amt.
Adding a LOCK to the program (e.g., L ^JNL(acct) just before the ZTSTART and a LOCK with no argument after the ZTCOMMIT,) isolates the transactions and prevents the two processes from overlapping. Because M does not treat the SET command as an atomic database operation, in the absence of TSTART/TCOMMIT commands, such LOCKs should exist independent of journaling considerations to protect the updates to ^AMT(d,acct) and ^JNL(0).