The following sections describe PSB scheduling, how to use an alternate PSB at run time, and how to share a PSB with a called program.
The PSB is scheduled whenever a DL/I call is issued for the program and the PSB is not currently scheduled. The PSB that is named in dliLib.psbData.psbName is the PSB scheduled.
When you use a call or transfer to program statement to transfer program control, the target program does not have to use the same PSB that the transferring program uses.
When you create a DL/I program, use the psb property to specify the name of a program variable that is based on a PSBRecord part. EGL uses the PSBRecord that is associated with this variable to create DL/I calls for the segments that are defined in the PSB and to validate the changes you make to the DL/I calls. In the CICS environment, Rational COBOL Runtime also uses the PSB name for PSB scheduling at the time the program is run.
However, you might want to use an alternate PSB with the same program. The alternate PSB describes databases that have the same structure as the program PSB, although the databases themselves might be different. For example, you could have a set of test databases for program development and a corresponding set of production databases that contain the real data for production.
If you want to use an alternate PSB, your program can dynamically change the scheduled PSB by moving the alternate PSB name into dliVar.dliPsbName before running the first DL/I function. The alternate PSB must match the program PSB except for the database names.
Called and calling programs cannot both be DL/I programs unless they share the same program PSB or unless a commit ends the PSB prior to each call or return to a program that uses a different PSB. When your program sets the callInterface property to CBLTDLI, you can share the PSB with another program by passing the dliLib.psbData structure or the PCB records on the call for both the called and the calling program. When your program sets the callInterface property to AIBTDLI (the default), pass the dliLib.psbData structure or the PCB records if the calling or called program is a non-EGL program.
If the called and calling programs are both EGL programs and the PSB was scheduled before the call, EGL does not reschedule the PSB in the called program.
You can share a PSB between EGL programs and non-EGL programs. When the dliLib.psbData structure is passed as a parameter, a 12-byte area is passed. The first 8 bytes contain the PSB name; the final 4 bytes contain the address of the CICS User Interface Block (UIB). If the PSB is not scheduled, the UIB address is 0.
When you share a PSB between EGL programs and non-EGL programs, the called program should check the UIB address before scheduling. If the UIB address is not 0, the PSB should not be rescheduled. If the called program ends the PSB, it must set the UIB address field to 0. If the PSB is scheduled again, the UIB address field should be set to the UIB address returned by CICS.
If a program needs to share a scheduled PSB with a called EGL program, it should pass a 12-byte area to the program. The first 8 bytes should contain the PSB name and the next 4 bytes should contain the UIB address. If the PSB is not scheduled, the UIB address should be 0. On return, the UIB address reflects the current scheduling status of the PSB.
When CICS detects a deadlock situation, it abnormally ends one of the programs, backs out the changes it made to the database, and writes an error message to the terminal explaining why the program ended.
If having a program abnormally end is unacceptable to the users of the program, you can define your program as restartable in the CICS tables. For information on restarting programs, see "Restarting EGL programs after a DL/I deadlock" in this topic.
If the program is restartable and CICS detects a deadlock situation, CICS backs out the changes that the program made since the PSB was scheduled and restarts the program from the beginning of the transaction.
If your program is running in segmented (CICS pseudoconversational) mode, the most recent segment of the program is restarted, and you do not need any special restart code in the program.
If a nonsegmented (CICS conversational) program is restarted, the program begins again at the top of the program. You can determine that the program was restarted by having the program test for a value of 1 in the dliVar.cicsRestart field. If dliVar.cicsRestart is 1, you can write a message to the program user explaining that the program was restarted because of a deadlock and then display the initial program map again.
When the DL/I program isolation facility is used, deadlocks can occur between two transactions that lock the same record. The programs try to update the same record at the same time. If both updates are accepted, one of the changes is lost. If CICS detects that data is lost, it abnormally ends the transaction with an ADLD abend code.
Otherwise, CICS writes a message that indicates the reason for program termination. A restarted program is a program that is started again from the beginning of the last transaction that was running. All changes to databases that were made since the program PSB was last scheduled are rolled back.
If restart is requested, programs running in segmented mode (CICS pseudoconversational) must have all the CICS resources that are to be updated defined as recoverable. The names of the temporary storage queues that are created by the segmentation function of Rational COBOL Runtime consist of the terminal identifier for the user appended to a 4-character prefix. The prefixes used are in the form of X'EE' followed by either WRK or MSG.
Programs that run on CICS can access DL/I databases on remote systems by calling a basic program that runs on the system where the database is located.