CICS® 環境では、PSB スケジューリングは非 CICS 環境とは異なる方法で処理されます。
以下のセクションでは、PSB スケジューリング、ランタイムに代替 PSB を使用する方法、および PSB を呼び出し先プログラムと共用する方法について説明します。
PSB は、DL/I 呼び出しがプログラムに対して発行されると、いつでもスケジュールに入れられます。PSB は現時点ではスケジュールに入っていません。 dliLib.psbData.psbName で指名されている PSB が、スケジュールに入る PSB です。
call または transfer to program ステートメントを使用してプログラムの制御権を移動する場合、ターゲット・プログラムは移動元のプログラムと同じ PSB を使用する必要はありません。
DL/I プログラムを作成する場合には、psb プロパティーを使用して PSBRecord パーツに基づいたプログラム変数の名前を指定します。 EGL はこの変数と関連付けられている PSBRecord を使用して、PSB で定義されているセグメントの DL/I 呼び出しを作成し、その DL/I 呼び出しに対して加えた変更の妥当性検査を行います。CICS 環境では、Rational COBOL Runtime は、プログラムの実行時に PSB スケジューリングに PSB 名も使用します。
しかし、同じプログラムで代替 PSB を使用する場合があります。代替 PSB はプログラムの PSB と同じ構造のデータベースを記述しますが、そのデータベースそのものとは異なる可能性があります。 例えば、プログラム開発のためのテスト・データベースのセット、および、実動のための本物のデータが入った、対応する実働データベースのセットが存在する可能性があります。
代替 PSB を使用する場合、プログラムは最初の DL/I 関数を実行する前にその代替 PSB の名前を dliVar.dliPsbName に移動することで、スケジュールに入っている PSB を動的に変更することができます。 代替 PSB はプログラム PSB と一致している必要がありますが、データベース名は除きます。
呼び出し先プログラムと呼び出し側プログラムが同じプログラム PSB を共用している場合や、各呼び出しの前に PSB を終了するコミットが行われた場合を除き、両方のプログラムを DL/I プログラムにすることはできません。そうした場合には、別の PSB を使用するプログラムに戻ります。 プログラムが callInterface プロパティーを CBLTDLI に設定した場合には、dliLib.psbData 構造または呼び出し先プログラムと呼び出し側プログラムの両方の呼び出し上の PCB レコードを渡すことで、別のプログラムと PSB を共用できます。 プログラムが callInterface プロパティーを AIBTDLI (デフォルト) に設定した場合は、呼び出し側プログラムまたは呼び出し先プログラムが非 EGL プログラムであれば、dliLib.psbData 構造または PCB レコードを渡します。
呼び出し先プログラムと呼び出し側プログラムがどちらの EGL プログラムで、その呼び出しの前に PSB がスケジュールされている場合、EGL は呼び出し先プログラム内の PSB のスケジュールを変更しません。
EGL プログラムと非 EGL プログラムの間で PSB を共用することは可能です。dliLib.psbData 構造をパラメーターとして渡す場合、12 バイトの領域が渡されます。 最初の 8 バイトには PSB 名が入り、残りの 4 バイトには CICS User Interface Block (UIB) のアドレスが入ります。 PSB がスケジュールされていない場合、UIB アドレスは 0 です。
EGL プログラムと非 EGL プログラムの間で PSB を共用する場合、呼び出し先プログラムはスケジューリングを行う前に、その UIB アドレスを検査する必要があります。 UIB が 0 以外の場合は、PSB のスケジュールを変更できません。 呼び出し先プログラムが PSB を終了する場合、そのプログラムは UIB アドレスを 0 に設定する必要があります。 PSB が再度スケジュールされる場合、UIB アドレス・フィールドは、CICS から戻された UIB アドレスに設定する必要があります。
プログラムが、スケジュールされている PSB を呼び出し先 EGL プログラムと共用する必要がある場合、そのプログラムは呼び出し先プログラムに、12 バイトの領域を渡す必要があります。最初の 8 バイトには PSB 名が入り、次の 4 バイトには UIB アドレスが入ります。 PSB がスケジュールされていない場合、UIB アドレスは 0 です。 それ以外の場合、UIB アドレスには、PSB の現在のスケジューリング状況が反映されます。
CICS がデッドロック状態を検出する場合、それはプログラムの 1 つを自動的に異常終了させ、データベースに行った変更をバックアウトし、プログラムが終了した理由を説明するエラー・メッセージを端末に書き込みます。
プログラムのユーザーがそのプログラムの異常終了を容認できない場合は、CICS テーブルでそのプログラムを restartable として定義することができます。 プログラムの再始動については、このトピックの『DL/I デッドロック後の EGL 生成プログラムの再始動』を参照してください。
プログラムが再始動可能に設定されている場合に CICS がデッドロック状態を検出すると、CICS は PSB のスケジューリング以降にそのプログラムが行った変更を取り消し、そのトランザクションの最初からプログラムを再始動します。
プログラムがセグメント化モード (CICS 疑似会話型) で実行されている場合には、そのプログラムの最新のセグメントが再始動されるため、プログラムの中に特別な再始動コードを組み込む必要はありません。
非セグメント化プログラム (CICS 会話型) が再始動される場合は、そのプログラムの最初からやり直しになります。 プログラムが再始動されたかどうかを判別するには、dliVar.cicsRestart フィールドに値 1 を入力して、プログラム・テストを行います。 dliVar.cicsRestart が 1 の場合、デッドロックが原因でプログラムが再始動したことをプログラムのユーザーに説明するメッセージを作成することができます。 そのメッセージの後には、初期プログラム・マップが再表示されます。
DL/I プログラム分離機能を使用している場合、デッドロックは同じレコード上の 2 つのトランザクション・ロックの間で発生する可能性があります。 複数のプログラムが同時に同じレコードの更新を試行したとします。 どちらの更新も受け入れられた場合、片方の変更は失われます。 データが失われたことを CICS が検出すると、そのトランザクションは ADLD 異常終了コードで異常終了します。
その他の場合、CICS はプログラム終了処理の理由を示すメッセージを書き込みます。 再始動されるプログラムは、実行していた最後のトランザクションの最初から再始動されます。 プログラム PSB が最後にスケジュールされてから後にデータベースに加えられた変更はすべて、ロールバックされます。
再始動が要求される場合、セグメント化モード (CICS 疑似会話型) で実行されているプログラムでは、更新済みのすべての CICS リソースがリカバリー可能として定義されている必要があります。Rational COBOL Runtime のセグメンテーション機能によって作成される一時ストレージ・キューの名前は、4 文字の接頭部と、これに追加したユーザーの端末 ID で構成されます。使用される接頭部の書式は X'EE' で、その後に WRK または MSG が続きます。
CICS で実行されているプログラムは、DL/I データベースが配置されているシステム上で実行される基本プログラムを呼び出すことで、リモート・システム上にあるその DL/I データベースにアクセスすることができます。