Issuing CMS Commands in a Work Unit
So far we have discussed work units as they are used in CSL routines. There are, however, ways to update files maintained by SFS without using the routines. For example, in high-level languages, you can execute CMS commands that operate on a file in the Shared File System by calling the routine DMSCCE to issue a command from an exec (you can issue the command directly from REXX). In assembler, you can execute CMS commands by issuing a macro such as CMSCALL or SUBCOM, or by issuing SVC 202 or SVC 204. There is no way to specify a work unit when issuing CMS commands from a program or exec directly, so SFS uses the default work unit. You can, however, alter the default work unit with DMSGETWU, DMSPUSWU, DMSPOPWU, and DMSRETWU and, thereby, indirectly specify the work unit for CMS commands.
The default work unit for CMS commands issued from programs and execs is the same as that used for CSL routines. (XEDIT and session services use their own work units for output files.) This assures updates are committed. Using the same default has several important implications for your programs.
Use DMSOPEN routine to open OUTFILE for output using default work unit ID
DO FOREVER:
prompt user for input
parse response
is response a CMS command we can execute?
Yes
Issue the command
No
If a valid response
Use DMSWRITE routine to write an appropriate record to OUTFILE
else
If end-of-conversation indicator
Use DMSCLOSE routine to close OUTFILE with the COMMIT option
end program
else
write message
endif
endif
END DO;
Suppose the user enters a CMS command. The program decides if it is valid and, if so, issues the command. If the command does not operate on a file in a SFS file pool, it does not matter to the program whether it succeeds or fails (unless it fails so dismally that it brings the program down with it). If it succeeds, the processing of OUTFILE is unaffected. If it fails, the same is true. Because the command does not operate on a file in a SFS file pool, no work unit ID is assigned to it. SFS does not know or care about the command.
Now, suppose the CMS command does operate on a file in an SFS file pool. In this case, SFS uses a default work unit ID. By coincidence, you have allowed the OPEN OUTFILE to default as well. They both have the same work unit ID, and the success or failure of both are linked together. Typically, CMS commands perform a commit, even on errors. If the CMS command fails in such a way that you roll back (receive return code 31) the changes, all changes in the work unit are rolled back. This includes both the changes caused by the CMS command before it failed and the changes previously made to OUTFILE — not necessarily the desired result, especially if many changes were already made to OUTFILE.
This situation may be avoided in one of the following ways:
- If you wish OUTFILE updates to be unaffected by the commits and
roll backs caused by CMS command processing, but require the capability
of rolling back OUTFILE updates explicitly, you must specify different
work unit IDs for the files used directly by your application (OUTFILE
in the previous example) and for those files accessed by CMS commands
issued through an exec, macro, or SVC. Because a default work unit
ID is always used for CMS commands issued from a program or exec,
you should obtain a different work unit ID to use with the SFS routines.
To fix the previous example, we would not let the work unit ID default
when we opened OUTFILE. Instead, we would obtain a work unit ID for
the SFS routines by adding the following to the beginning of the program:
WORK1 = buffer for work unit ID CALL DMSCSL (DMSGETWU, RETCODE, REASCODE, WORK1) Use DMSOPEN routine to open OUTFILE for output using workunitid=WORK1
- If do not wish updates to OUTFILE to be rolled back even if your
application experiences a failure, you should define OUTFILE as a
nonrecoverable file. Using this approach, commits and rollbacks of
the work unit caused by both CMS command processing and by your program
will cause OUTFILE updates to be committed (where possible). Using
this approach, you may fix the previous example by recoding the OPEN
statement to include the NORECOVER option.
Note: There are a number of ways to define files with the attribute of NORECOVER. Some of them may be used in conjunction with compatibility interfaces (such as EXECIO and FSWRITE). See Using the Recoverability and Overwrite Attributes for a further discussion of the recoverability attribute.