Logical unit of work

When you change non-recoverable resources, such as serial files on Windows 2000, that change is relatively permanent; neither your code nor EGL runtime services can rescind the changes without notice. When you change recoverable resources, such as databases, your code or EGL runtime services can either commit the changes to make them permanent or roll back the changes to return to content that was in effect the last time changes were committed.

You can recover the following resources:
  • Relational databases
  • CICS® queues and files that are configured to be recoverable
  • DL/I databases and GSAM files (in some cases)
  • WebSphere® MQ message queues, unless your MQ record specifies otherwise
  • Output that is directed to alternate PCBs; alternate PCBs are available when the target system is IMS BMP or IMS/VS
A logical unit of work identifies input operations that are either committed or rolled back as a group. A unit of work begins when your code changes a recoverable resource and ends when the first of the following events occurs:
  • Your code invokes the sysLib.commit() or sysLib.rollback() system functions to commit or roll back the changes.
  • EGL runtime services performs a rollback in response to a hard error that is not handled in your code; in this case, all the programs in the run unit are removed from memory.
  • An implicit commit occurs, as in the following cases:
    • A run unit ends successfully; see Run unit.
    • A program issues a show statement.
    • A program issues a transfer to transaction statement, with the following distinctions:
      • In a program that runs under CICS® or IMS/VS, the transfer always causes a commit.
      • In other programs, the transfer causes a commit only if the value of the synchOnTrxTransfer build descriptor option is YES.
    • A Text UI program issues a converse statement when the program is acting as a segmented program.

If the program runs in a transactional environment (CICS®, IMS, or iSeries®), EGL issues an environment commit that performs a two-phase commit coordinated across all resource managers and across all programs in the run unit. In non-transactional environments, EGL performs a single phase commit that calls each recoverable resource manager separately.

If a program runs in z/OS® batch and accesses DB2®, it can run in an RRSAF environment:
  • To enable this capability, use the ELACPIOP sample JCL to generate a new version of ELARPIOP. The ELACPIOP sample JCL is the ELAJCL dataset that is created during the customization of the IBM® Rational® COBOL Runtime for zSeries product.
    You have two choices:
    • Repeat the installation customization that is specified in section 6.2.1.2.2 of the Program Directory; or
    • Modify the ELACPIOP JCL by adding the RRSAF=Y parameter, as shown here:
      ELARMIOP NLS=ENU,EOF=N,SCFOLD=Y,IMSESA=N,SEGMSG=N,            X
        MSGTRN=ELAE,TRBUF=64,TSQUE=32,RRSAF=Y  
  • The following files must be changed to enable the usage of RRSAF:
    • The JCL or EGL Build scripts that are used to precompile your program; and
    • The execution JCL that is used to run the batch job.

    Additional details are in the DB2® RRSAF documentation.

  • The EGL support described earlier is only for implicit RRSAF database connections. If you are using explicit database connections when running code under RRSAF, you need to update your EGL program.

    Additional details are in the DB2® RRSAF documentation.

The following considerations apply to the interaction of EGL and non-EGL programs.
  • If an EGL program calls a non-EGL program and both programs access SQL tables, you must close all cursors before the call if the non-EGL program causes a commit or rollback.
  • In non-transactional environments, if any of the EGL programs in a run unit does not perform SQL, but calls or transfers to a non-EGL program that does SQL I/O, then EGL does not issue a commit at the end of the run unit.
When you invoke the sqlLib.connect() or vgLib.connectionService() system functions (either of which you can use to connect dynamically to a different database), precede the invocation with an invocation of sysLib.commit() or sysLib.rollback().

Compatibility

Table 1. Compatibility considerations for unit of work
Platform Issue
Java generation
  • When any of the Java programs ends with a hard error, the effect is equivalent to performing rollbacks, closing cursors, and releasing locks.
  • When the run unit ends successfully, EGL performs a commit, closes cursors, and releases locks.
  • You can use multiple connections to read from multiple databases, but do not update more than one database in a unit of work because only a one-phase commit is available. For more information, see connect().
  • When you are writing a mixture of native and generated Java and need to commit SQL database changes that were made earlier in the run unit, you can use the Java class described in "SharedResourcePowerServer."
CICS®
In a CICS® run unit, only one DB2® UDB database is available at a time; automatic processing occurs in the following manner:
  • When any of the programs ends with a hard error, EGL runtime services performs a rollback, closes cursors, and releases locks.
  • When the run unit ends successfully, CICS® performs a commit, closes cursors, and releases locks unless the caller requests that those actions not occur. For example, those actions do not occur if Java code accesses an EGL CICS® program and the linkage options part for the call indicates that the Java code handles the logical unit of work. In this case, the logical unit of work is called the client unit of work. For more information, see the EGL Generation Guide.
A commit occurs in the following cases, which are related to DL/I processing:
  • A program called by EGL that accesses DL/I returns to the calling program, when the parameter list of the called program did not include the address of a PCB or PSB.
  • A PSB is currently scheduled, an EGL program transfers using transfer to program, and one of the following conditions applies:
    • The transfer is to a non-EGL (and non-VisualAge Generator) program.
    • The synchOnPgmTransfer build descriptor option is set to YES for the transferring program.
    • The synchOnPgmTransfer build descriptor option is set to NO for the transferring program and the default PSB that is referenced in the PSB record of the transferring program is different from the default PSB that is referenced in the PSB record of the target program. (To minimize the differences in behavior when a transferring program is generated for both CICS® and IMS/VS, set the synchOnPgmTransfer build descriptor option to NO.)
IMS BMP
sysLib.commit() is ignored for transaction-oriented BMP programs in which the program uses a get next statement to read a serial file that is associated with the I/O PCB. For these programs, the system performs the commit in any of the following conditions:
  • Each time a get next statement for the serial file that is associated with the I/O PCB results in a get unique (GU) call to retrieve the first segment of the next message.
  • Whenever you use dliLib.AIBTDLI(), dliLib.EGLTDLI(), or vgLib.VGTDLI() to issue a CHKP call or a get unique (GU) call to the I/O PCB.
For a batch-oriented BMP program that does not use a get next statement to read a serial file that is associated with the I/O PCB, invoking sysLib.commit() results in a DL/I basic CHKP call. This call commits changes to all databases. The contents of the dliLib.psbData.psbName structure are used as the checkpoint identifier on the CHKP call.

GSAM files are not recoverable when used with basic CHKP. To make GSAM files recoverable, use dliLib.AIBTDLI(), dliLib.EGLTDLI(), or vgLib.VGTDLI() for symbolic checkpoint instead of sysLib.commit().

IMS/VS
sysLib.commit() is ignored. Commit processing only occurs at the following implicit commit points:
  • For a Text UI program, at each converse statement or when the run unit ends successfully, as described in Run unit.
  • For a basic program, the system performs the commit in the following manner:
    • Each time a get next statement for the serial file that is associated with the I/O PCB results in a get unique (GU) call to retrieve the first segment of the next message.
    • Whenever you use dliLib.AIBTDLI, dliLib.EGLTDLI, or vgLib.VGTDLI to issue a CHKP call or a get unique (GU) call to the I/O PCB.
Changes to all databases and serial files are committed at the implicit commit points.
In relation to the logical unit of work, an explicit checkpoint command (CHXP) causes a get unique (GU) call to the I/O PCB, which in turn causes a commit. The following warnings apply:
  • Never issue the CHKP command in a text UI program, as the result interferes with the way the generated COBOL program interacts with the input message queue.
  • Do not issue the CHKP command in a basic program, even if you are handling the I/O PCB access explicitly in the code.
iSeries® COBOL
An implicit commit is issued in the following situations:
  • When a main Text UI program ends, which constitutes the end of a run unit. The most common instance of this is when the main Text UI program returns to the non-EGL (or non-VisualAge Generator) program from which it was started.
  • When a program issues a transfer to transaction statement.

If the program has issued SQL requests, invoking a sysLib.commit() results in an SQL COMMIT WORK statement. If the program has not issued SQL requests, invoking a sysLib.commit() results in the equivalent of an iSeries® COMMIT command.

z/OS® batch

If the program does not specify a PSB but has issued SQL requests, invoking sysLib.commit() results in an SQL COMMIT WORK statement.

If the program has a PSB specified, invoking sysLib.commit() results in a DL/I basic CHKP call, which commits changes to all databases. The contents of the dliLib.psbData.psbName structure act as the checkpoint identifier on the CHKP call.

GSAM files are not recoverable when used with basic CHKP. To make GSAM files recoverable, use dliLib.AIBTDLI(), dliLib.EGLTDLI(), or vgLib.VGTDLI() for symbolic checkpoint instead of sysLib.commit().