CICS 環境のための DL/I 考慮事項

CICS® 環境では、 PSB スケジューリングの処理は、非 CICS 環境とは異なります。 以下のセクションでは、PSB スケジューリング、実行時に代替 PSB を使用する方法、および 呼び出し先プログラムで PSB を共用する方法について説明します。

PSB スケジューリングの理解

CICS DL/I プログラムが PSB で定義されたデータベースにアクセスするには、プログラムで先にその PSB をスケジュールしなければなりません。 データベース・アクセスが完了したとき、プログラムは PSB を終了する必要があります。 Enterprise Developer Server for z/OS® はプログラムの PSB スケジューリングを自動的に処理します。 ただし、以下の機能が PSB スケジューリングによる影響を受けるので、ユーザーはいつ PSB がスケジュールされるのかを知る必要があります。
セグメント・レコードのロック
セグメント更新ロックは、PSB が終了したときに開放されます。
データベース位置
データベース位置は、PSB が終了したときに失われます。
コミットメント更新
PSB が終了したとき、変更がコミット (データベースへの書き込み) されます。
DL/I 呼び出しがプログラムに発行されていて、しかも PSB が現在スケジュールに入れられていないときは常に、PSB がスケジュールされます。 dliLib.psbData.psbName で指名された PSB は、スケジュールされている PSB です。

プログラム制御権の移動を行うために CALL または DXFR 文を使用するとき、 プログラム制御権の移動先プログラムは、移動元プログラムが使用するものと同じ PSB を使用する必要はありません。

PSB は、CICS SYNCPOINT または SYNCPOINT ROLLBACK が発行されると常に、終了します。 以下のいずれか 1 つが起こるとき、SYNCPOINT が発生します。
  • 実行単位内のトップレベルのプログラムが正常に終了し、 CICS に制御権を戻す。 CICS の場合、実行単位は、単一トランザクションに相当し、 DXFR または CALL 文を使用して相互に制御権移動を行うすべての EGL プログラム および非 EGL プログラムから構成されます。 非 EGL プログラムの場合、これには、CALL 文、CICS LINK コマンド、または CICS XCTL コマンドを使用するすべての移動も含まれます。
  • プログラムが CONVERSE I/O オプションを使用して、以下のどちらかが 1 に設定された。
    • converseVar.segmentedMode (プログラムがセグメントとして定義される場合、1 にデフォルト設定)
    • converseVar.commitOnConverse
  • XFER 文を使用する移動が行われる。
  • プログラムが、sysLib.commit() 関数または COMMIT サービスのどちらかを呼び出す。
  • DXFR 文を使用する移動が行われ、PSB がスケジュールされ、以下のうちの 1 つが発生した。
    • PSB がスケジュールされたときの非 EGL プログラムへの移動。
    • synchOnPgmTransfer 生成オプションが、移動元プログラムに対して yes に設定された。
    • synchOnPgmTransfer 生成オプションが、移動元プログラムに対して no に設定され、 2 つのプログラムのプログラム仕様で、異なった PSB 名が識別された。
  • EGL 呼び出しの DL/I プログラムが、呼び出し側の非 EGL プログラムに戻り、 PSB が DLILib.psbData 構造に渡されず、また PCB は、PCB レコードを使用して渡されなかった。
SYNCPOINT ROLLBACK は以下の場合に行われます。
  • EGL プログラムが、sysLib.rollback() 関数または RESET サービスを呼び出す。
  • エラー状態のため、プログラムが終了した。
ロールバックが発生すると、作業論理単位 (LUW) の開始以降にデータベースとリカバリー可能ファイルに作成された変更のすべてがバックアウトされます。

実行時の代替 PSB の使用

EGL は、PSB で定義されたセグメントに対し DL/I 呼び出しを作成するため、 また DL/I 呼び出しに行ったすべての変更を検証するために、プログラム仕様に名前が指定された PSB を使用します。 CICS 環境では、 Enterprise Developer Server for z/OS は、プログラムが実行された時点での PSB スケジューリングにも PSB 名を使用します。

しかし、ユーザーが同一のプログラムで代替 PSB の使用を望む場合があります。 代替 PSB は、プログラム PSB と全く同じ構造を持つデータベースを記述しますが、データベースそのものは異なる可能性があります。 例えば、ユーザーは、プログラム開発用のテスト・データベースのセットと、実動用の実データを含む、 対応する実動データベース・セットを持つことがあります。

何らかの理由で代替の PSB を使用したい場合、ご使用のプログラムで、最初の DL/I 関数を実行する前に、代替 PSB 名を DLIVar.dliPsbName へ移動することによって、スケジュールされている PSB を動的に変更することができます。 代替 PSB はプログラム PSB に一致しなければなりません (ただし、データベース名は異なってもかまいません)。

スケジュールされた PSB の呼び出し先プログラムとの共用

呼び出し先プログラムと呼び出し側プログラムは、両方が同じプログラム PSB を共用するか、 各呼び出しの前にコミットが PSB を終了させ、異なる PSB を使用するプログラムに戻らない限り、 どちらも DL/I プログラムにはなりません。 呼び出し先プログラムと呼び出し側プログラムの両方に対して、 呼び出し時に DLILib.psbData 構造または PCB レコードを受け渡すことにより、PSB は共用されます。

呼び出し先プログラムおよび呼び出し側プログラムが両方とも EGL プログラムである場合、および PSB が呼び出しの前にスケジュールされた場合、EGL は呼び出し先プログラムの PSB をスケジュール変更しません。

EGL プログラムと非 EGL プログラム間で PSB を共用することができます。DLILib.psbData 構造がパラメーターとして受け渡されるとき、実際には 12 バイトの領域が受け渡されます。 最初の 8 バイトは PSB 名を含み、最後の 4 バイトは、CICS ユーザー・インターフェース・ブロック (UIB) のアドレスを含みます。 PSB がスケジュールに入れられない場合、UIB アドレスは 0 です。 EGL プログラムと非 EGL プログラム間の PSB を共用する場合、 呼び出し先プログラムは、スケジュールに入れる前に UIB アドレスを確認しなければなりません。 UIB アドレスが 0 でない場合は、PSB はスケジュール変更をしてはなりません。 呼び出し先プログラムは、PSB を終了する場合、UIB アドレス・フィールドを 0 に設定しなければなりません。 PSB が再びスケジュールに入れられる場合、UIB アドレス・フィールドを、 CICS により戻された UIB アドレスに設定しなければなりません。

プログラムが、呼び出し先 EGL プログラムとスケジュールに入れられた PSB を共用する必要がある場合、 12 バイトの領域をプログラムに受け渡さなければなりません。 一方、最初の 8 バイトには PSB 名を含み、次の 4 バイトには UIB アドレスを含む必要があります。 PSB がスケジュールされない場合、UIB アドレスは 0 でなければなりません。 戻り時、UIB アドレスは PSB の現在のスケジューリング状況を反映します。

レコード・キューイングにおけるデッドロック後の回復

更新されたレコードは、PSB が終了するまで、実際にはデータベースに書き込まれていません。 EGL get...forUpdate I/O 文によって、 レコードがデータベースに実際に書き込まれるまで、他のプログラムが 再びレコードを変更しないようにロックアウトするので、プログラムは PSB 終了までレコードの排他使用権を得ます。 これにより、プログラムがなんらかのレコードをロックしたが、今度は、 ロックされたレコードを必要とする他のプログラムによりロックされたレコードを変更したいという、 デッドロック状態が発生する可能性があります。 CICS は、デッドロック状態を検出すると、 プログラムの 1 つを異常終了させ、データベースに行った変更を取り消し、 プログラムが終了した理由について説明するエラー・メッセージを端末に書き込みます。

プログラムのユーザーにとって、プログラムが異常終了することが容認できない場合、 CICS テーブルで、 プログラムを再起動可能と定義できます。プログラムの再始動に関する情報に関ついては、 このトピックの後半にある『DL/I デッドロック後の EGL 生成プログラムの再始動』を参照してください。

プログラムが再始動可能であり、かつ CICS がデッドロック状態を検出した場合、 CICS は PSB が スケジュールされた後にプログラムが行った変更を取り消し、 トランザクションの最初からプログラムを再始動します。

プログラムがセグメントされた (疑似会話型) モードで実行されている場合、プログラムの最新のセグメントが再始動されるため、 ユーザーが、プログラム内に特別な再始動コードを定義する必要はありません。

会話型プログラムが再始動されると、プログラムは先頭で再び開始されます。 DLIVar.cicsRestart フィールドの値が 1 であるかどうかをプログラムにテストさせることによって、 プログラムが再始動されたかどうか判別することができます。 DLIVar.cicsRestart が 1 である場合、 デッドロックによりプログラムが再始動されたというメッセージをプログラム・ユーザーに向けて書き出してから、 再び初期プログラム・マップを表示することができます。

DL/I デッドロック後の EGL 生成プログラムの再始動

DL/I プログラム分離機能が使用されている場合、同一レコードでロックしている 2 つのトランザクション間にデッドロックが起こる可能性があります。 それらのプログラムは同時に、同一レコードの更新を試みます。 両方の更新が受け入れられるならば、変更点の 1 つは失われます。 CICS は、データの逸失を検出した場合、ADLD 異常終了コードを出してトランザクションを異常終了します。

Enterprise Developer Server for z/OS 異常終了ハンドラーは、 デッドロック異常終了で終了したプログラムの再始動を要求します。 以下の場合、CICS はトランザクションを最初から開始します。
  • トランザクション・プログラムのための PCT で、DTB=YES および RESTART=YES を指定した。
  • CICS トランザクション の再始動プログラム (DFHRTY) が、トランザクションの再始動を指定した。
  • 一時ストレージ・キューがリカバリー可能と定義された。

その他の場合、CICS は、プログラムの終了の理由を示すメッセージを書き込みます。 再始動されたプログラムは、実行されていた最後のトランザクションの先頭から再び始動されたプログラムです。 プログラム PSB が最後にスケジュールされて以降、データベースへ行われたすべての変更はロールバックされます。

CICS 再始動プログラム (DFHRTY) の配布バージョンでは、 EGL 生成プログラムを、実行されていた最後のデータベース・トランザクションを最初から再始動しません。 EGL データベース・トランザクションを再始動するために、コードを DFHRTY に追加することができます。 プログラムでは、以下が真であるかをチェックする必要があります。
  • 現在の異常終了コードは ADLD。
  • トランザクション ID は、再始動したいトランザクションの ID。
  • 再始動カウントは、指定より小さい数。これは再始動のループ検査です。
すべての検査が適合すると、プログラムでは再始動フラグを on に設定して、 再始動が続くことを CICS に示す必要があります。 DFHRTY の変更に関する詳細情報については、 ご使用の CICS システムのリカバリー、再始動、およびカスタマイズの関連マニュアルを参照してください。

セグメント化モードで実行中のプログラムは、再始動が要求された場合、すべての CICS リソース (更新される予定のリソース) をリカバリー可能と定義していなければなりません。 Enterprise Developer Server for z/OS のセグメンテーション関数で作成される一時ストレージ・キューの名前は、 4 文字の接頭部にユーザーの端末 ID を追加して組み合わせたものです。 使用される接頭部は、X‘EE‘ に続いて WRK または MSG が来る形式をとります。

再始動を処理するようにプログラムを設計しておかないと、 会話型プログラムに対して再始動を要求できません。 現行のプログラム・トランザクションが再始動されたかどうかをプログラムが知るには、 DLIVar.cicsRestart フィールドをテストすることができます。 再始動のためにプログラムを設計する簡単な方法の 1 つは、 プログラムの開始時に常に、cicsRestart をプログラムにテストさせることです。 再始動フラグが on の場合、ユーザー 2 が同時にデータベースを変更しているので、 トランザクションが先頭で再始動されたことを説明する特別なメッセージまたはマップがユーザー 1 に、表示されるはずです。 ユーザー 1 の変更点はバックアウトされ、変更点が失われるのを防ぐためにプログラムが再始動されました。

分散 DL/I データベースのアクセス

CICS 上で実行しているプログラムは、データベースが配置されているシステムで実行している バッチ・プログラムを呼び出すことで、リモート・システム上の DL/I データベースにアクセスできます。

フィードバック
(C) Copyright IBM Corporation 2000, 2005. All Rights Reserved.