When an application is defined to CICS® as quasi-reentrant, it executes on the
QR TCB. When running under this TCB, a program can be sure that no other quasi-reentrant
program can run until it relinquishes control during a CICS request. Quasi-reentrancy
therefore allows programs to access globally shared resources--for example,
the CICS common work area (CWA)--without the need to protect those resources
from concurrent access by other programs. Such resources are effectively locked
exclusively to the running program, until it issues its next CICS request.
In the CICS open transaction environment (OTE), when application programs, task-related
user exits (TRUEs), global user exit programs, and user-replaceable modules
are defined to CICS as threadsafe, they can run concurrently on open TCBs.
Because of this, they cannot rely on quasi-reentrancy to protect shared resources
from concurrent access by another program. Furthermore, quasi-reentrant programs
might also be placed at risk if they access shared resources that can also
be accessed by a user task running concurrently under an open TCB. The techniques
used by user programs to access shared resources must therefore take into
account the possibility of simultaneous access by other programs. To gain
the performance benefits of the open transaction environment while maintaining
the integrity of shared resources, serialization techniques must be used to
prohibit concurrent access to shared resources. Programs that use appropriate
serialization techniques when accessing shared resources are described as
threadsafe.
As we saw in What is the open transaction environment and how can I benefit from
it?, only applications that
involve a task-related user exit (TRUE) enabled using the OPENAPI option,
such as applications which access DB2® resources, can gain performance benefits
from being threadsafe. These are the only applications that might or might
not be able to run on an open TCB.
The goal of making programs threadsafe is to enable them to remain on an
open TCB, rather than switching back and forth between the open TCB and the
QR TCB. TCB switching occurs in the following circumstances:
- When a program that is not defined as threadsafe makes a DB2 request, CICS switches from the QR TCB (where the program is executing) to an open
TCB, and back to the QR TCB again when the DB2 request is complete.
- When a user exit program that is not defined as threadsafe is used in
the course of a DB2 request, CICS switches from the open TCB (where the DB2 request
is executing) to the QR TCB. The user exit program is executed on the QR TCB,
and then the task is switched back to the open TCB to complete the DB2 request. For
example, the XRMIIN and XRMIOUT global user exits might be invoked in the
course of the DB2 request. If the exit programs are not defined as threadsafe, this
TCB switching occurs. If the exit programs are defined as threadsafe, processing
will continue throughout on the open TCB.
- When a program that is defined as threadsafe and is executing on an open
TCB invokes any EXEC CICS commands which are not threadsafe, CICS switches back
from the open TCB to the QR TCB to execute the non-threadsafe code. The program
then continues to execute on the QR TCB. If the program does not make any
further DB2 requests, then the switch back to the QR TCB is only a disadvantage
because it increases the usage of your QR TCB for the time taken to run any
remaining application code. However, if the program makes any further DB2 requests, CICS must switch back again to the open TCB.
- When a program that is defined as threadsafe and is executing on an open
TCB invokes a task-related user exit program which is not defined as threadsafe, CICS switches back to the QR TCB and gives control to the task-related user
exit program. When the task-related user exit program completes processing,
the application program continues to execute on the QR TCB, in the same way
as it would after issuing a non-threadsafe EXEC CICS command.
- When a program that is defined as threadsafe and is executing on an open
TCB invokes a threadsafe CICS command, it is possible for a global user exit to
be invoked as part of executing the command. If a global user exit program
is used which is not defined as threadsafe, CICS switches back to the QR TCB and gives
control to the global user exit program. When the user exit program completes
processing, CICS switches back to the open TCB to continue processing the threadsafe CICS command.
- When a program that is defined as threadsafe and is executing on an open
TCB completes, CICS switches back to the QR TCB for task termination.
This switch is always necessary.
The maximum TCB switching for a CICS DB2 application would occur if your program
used a non-threadsafe user exit program and a non-threadsafe EXEC CICS command after
every DB2 request.
If you want to make an application program remain on an open TCB:
- Ensure that the program's logic is threadsafe. That
is, the native language code between the EXEC CICS commands must be threadsafe. If you define
a program to CICS as threadsafe but include application logic that is not threadsafe,
the results are unpredictable, and CICS is not able to protect you from the possible
consequences. "Threadsafe programs" in the CICS Application Programming Guide tells
you how to produce threadsafe application logic.
- Ensure that the program uses only threadsafe EXEC CICS commands. The commands that are threadsafe are indicated in the
command syntax diagrams in the CICS Application Programming Reference and the CICS System Programming Reference with the statement "This command is
threadsafe", and are listed in "Threadsafe command list"
in the CICS Application Programming Reference and Appendix D of the CICS System Programming Reference.
If you include a non-threadsafe EXEC CICS command in a program which is running
on an open TCB, CICS switches back from the open TCB to the QR TCB to ensure
that the command is processed safely. The TCB switching could be detrimental
to the application's performance.
As
well as checking EXEC CICS commands that you code explicitly, be aware of
high-level language constructs or Language Environment callable services used
by your program that result in using CICS services. CICS services used in
this way might involve non-threadsafe CICS commands, and cause a switch back
to the QR TCB. In particular, the COBOL statement DISPLAY UPON SYSOUT, some
types of PL/I and C++ output, and the Language Environment callable
services CEEMOUT and CEE3DMP, write data to the Language Environment transient
data destinations CESE and CESO. This involves an EXEC CICS WRITE TD command,
which is not threadsafe.
- Ensure that the program is defined to CICS as threadsafe. Use the CONCURRENCY attribute of the program resource definition to
do this. By defining a program to CICS as threadsafe, you are only specifying
that the application logic is threadsafe, not that all the EXEC CICS commands included
in the program are threadsafe. CICS can ensure that EXEC CICS commands are
processed safely by using TCB switching. In order to permit your program to
run on an open TCB, CICS needs you to guarantee that your application logic
is threadsafe.
- Ensure that any user exit programs in the execution path
used by the program are coded to threadsafe standards and defined to CICS as threadsafe. This might include dynamic plan
exits, global user exits, or task-related user exits. (Note for task-related
user exits, enabling the exit program using the OPENAPI option on the ENABLE
PROGRAM command means that CICS overrides the CONCURRENCY setting on
the exit's program definition with OPENAPI.) When CICS is connected to DB2 Version 6 or later, the CICS DB2 task-related
user exit DFHD2EX1 is threadsafe. "SQL, threadsafe
and other programming considerations for CICS DB2 applications" in the CICS DB2 Guide has
more information on other exits that are particularly important for CICS DB2 requests. These
exits include the default dynamic plan exit DSNCUEXT (which is not defined
as threadsafe), the alternative dynamic plan exit DFHD2PXT (which is defined
as threadsafe), and the global user exits XRMIIN and XRMIOUT. Also be aware
of the global user exits XEIIN and XEIOUT, which are invoked before and after
EXEC CICS commands, and XPCFTCH, which is invoked before a PPT-defined program
receives control. Be sure that user exit programs supplied by any vendor software
are coded to threadsafe standards and defined to CICS as threadsafe.
- If you are coding a user exit program (a global
user exit or a task-related user exit), you can define it as threadsafe so
that it can be used on the same L8 TCB as a threadsafe application which calls
it. Additionally, a task-related user exit can be enabled using the OPENAPI
option on the ENABLE PROGRAM command so that it will be given control under
an L8 TCB, use non-CICS APIs without having to create and manage subtask TCBs,
and exploit the open transaction environment for itself. (Enabling the exit
program using the OPENAPI option on the ENABLE PROGRAM command means that CICS overrides the CONCURRENCY setting on the exit's program definition with
OPENAPI.) Global user exit programs can be treated in the same way as an ordinary
application program--by using threadsafe application logic and threadsafe
EXEC CICS commands, and defining the program as threadsafe. "Writing global user exit programs" in the CICS Customization Guide has general
information about writing this type of program. For task-related user exit
programs, see "Writing a task-related user exit
program" in the CICS Customization Guide for more detailed information about how
this type of program can exploit the open transaction environment safely.
Note when you enable an exit program using the OPENAPI option, this indicates
to CICS that the program's logic is threadsafe.
[[ Contents Previous Page | Next Page Index ]]