IMS プログラムのコード例

EGL プログラムから抜粋した以下のコードは、IMS™ 端末、メッセージ・キュー、およびシリアル・ファイルとの対話を示しています。

メッセージ・キューに関連付けられているシリアル・ファイルへの出力の例

以下に、メッセージ・キューにアクセスする EGL プログラムから抜粋したコードを示します。 このプログラムは以下のタスクを実行します。
  1. フォームを使用して端末からの入力を要求する。
  2. 応答を読み取る。
  3. ユーザー入力に基づく情報を使用して、シリアル・レコードを更新する。
  4. 後でバッチ処理を行うために、シリアル・レコードを別のトランザクションに出力する。
このプログラムでは、IMS 環境に以下の関連があることを想定しています。
  • IMS トランザクション・コード MYTRXCD1 は、MYTRXCD1 という名前の PSB に関連付けられている。
  • IMS トランザクション・コード NEXTTRX は、MYTRXCD2 という名前の PSB に関連付けられている。
//define PSB
Record addToQueue type PSBRecord { defaultPSBName="MYTRXCD1" }
   // three PCBs required for CBLTDLI on IMS
   iopcb IO_PCBRecord { @PCB { pcbType = TP } };
   elaalt ALT_PCBRecord { @PCB { pcbType = TP } };
   elaexp ALT_PCBRecord { @PCB { pcbType = TP } };
   // other database PCBs
   ...
end


Record myTransactionPart type serialRecord
   { fileName="MYMSGQUE" }
   ...
end

program addtrans type textUIProgram
   { alias = "MYTRXCD1",           // IMS requires pgm to match PSB name
      segmented = yes,
      @DLI { psb = "mypsb" }}

use MYFORMS;  // MYFORMS is a formGroup containing FORM1

// declare variables
myTransaction myTransactionPart;  // serial record for message queue
mypsb addToQueue;                 // psb

   function main()
      ...
      converse FORM1;  
      // do whatever processing is necessary
      move FORM1 to myTransaction byName;
      add myTransaction;
      ...
   end
end
生成時には、シリアル・ファイルをメッセージ・キューに関連付け、そのメッセージ・キューの送信先であるトランザクションの名前を提供するリソース関連パーツを、使用する PCB の名前とともに指定する必要があります。以下の例を考えてみましょう。この例には、後述するように、バッチ・プログラムによってメッセージ・キュー・データの入力を可能にする association 要素も含まれています。
<ResourceAssociations name="IMS_RESOURCE_ASSOCIATION">
   <association fileName="MYMSGQUE">
      <imsvs>
         <smsgq systemName="NEXTTRX" pcbName="elaalt"/>
      </imsvs>
   </association>   
   <association fileName="MYINQUE">
      <imsvs>
         <smsgq systemName="NEXTTRX" pcbName="iopcb"/>
      </imsvs>
   </association>
</ResourceAssociations>

addtrans は textUI プログラムであるため、EGL は IMS 環境とインターフェースするための制御ロジックを生成します。IMS プログラムは、入力メッセージ・キューが空になるまで、そのキューを読み取ることが期待されています。したがって EGL は、プログラムが (converse または show ステートメントを使用して) 現行ユーザーに応答するか、または (transfer to transaction ステートメントを使用して) 応答の責務を転送すると、プログラムがループしてメッセージ・キューから次の入力メッセージを読み取るよう、プログラムにロジックを生成します。概要については IMS での端末との対話を参照してください。詳細については、このトピックの『複数のユーザーおよびメッセージ・キュー』を参照してください。

IMS バッチ処理の例

プログラム addtrans がメッセージ・キューに書き込むメッセージを処理するためのプログラムを作成することもできます。このプログラムは、シリアル・ファイルからレコードを取得して、そのシリアル・ファイルを入出力 PCB に関連付ける基本プログラムである必要があります。

このプログラムでは、addtrans が使用したのと同じシリアル・レコードを新しいファイル名で使用することができます。その理由は、異なる PCB 名が必要であるからです。以下の例では、主な変更が太字で示されています。
//define PSB
Record getFromQueue type PSBRecord { defaultPSBName="MYTRXCD2" }
   // three PCBs required for CBLTDLI on IMS
   iopcb IO_PCBRecord { @PCB { pcbType = TP } }
   elaalt ALT_PCBRecord { @PCB { pcbType = TP } };
   elaexp ALT_PCBRecord { @PCB { pcbType = TP } };
   // other database PCBs
end

program gettrans type basicProgram
   { alias = "MYTRXCD2"
      @DLI { psb = "mypsb" }}

// declare variables
myTransaction myTransactionPart             // serial record for message queue
   {fileName="MYINQUE"};  
mypsb getFromQueue;               // psb

   function main()
      while (myTransaction not endOfFile)
         get next myTransaction;
      // do whatever processing is necessary
      end
   end
end

IMS/VS または IMS BMP 環境用のプログラムを生成する場合は、シリアル・ファイルをメッセージ・キューに関連付けるリソース関連パーツも、使用する PCB の名前とともに指定する必要があります。この場合、入出力 PCB は、前のセクションの ResourceAssociations パーツで示しているように、入力に使用されます。systemName プロパティーはオプションです。このプログラムは、IMS システム定義に基づき、このプログラムを開始したトランザクションに関連付けられているメッセージ・キューを読み取ります。EGL は入力メッセージ内の IMS トランザクション ID に基づき、sysVar.transactionID を設定します。

複数のユーザーおよびメッセージ・キュー

EGL プログラムの作成時に必要なのは、単一の端末における単一ユーザーに対して行う必要のある処理を検討することだけです。EGL は、リソースを要求して競合している複数のユーザーがいる場合の、IMS における複雑な状態を処理するために、制御ロジックをプログラムに生成します。USER1 と USER2 がどちらも自分の端末で同時に MYTRXCD1 を入力したと想定します。USER1 のトランザクション・コードが、MYTRXCD1 に関連付けられているメッセージ・キューで最初に終了したとします。
  1. IMS は、トランザクション・コード MYTRXCD1 に関連付けられている PSB をスケジュールに入れます。その PSB も偶然 MYTRXCD1 という名前が付けられています (この名前である必要はありません)。しかし、PSB に関連付けられているプログラムは、IMS では PSB と同じ名前である必要があります。したがって、IMS はプログラム MYTRXCD1 (EGL では addtrans という名前です) をロードします。
  2. EGL によってプログラム MYTRXCD1 に生成された制御ロジックは、USER1 に対して今回初めてこのプログラムが呼び出されたと判断して、一番上から順に処理を開始します。
  3. プログラムは最終的には converse ステートメントに到達し、以下のアクションを実行します。
    • プログラムが使用しているすべてのレコードとフォームのデータを保存します。
    • converse ステートメントがプログラム内で発生した場所ついての情報を保存します。
    • 指定されたフォームを使用して ISRT コマンドを実行します。
  4. EGL が追加したロジックに従って、プログラムは先頭にループバックし、メッセージ・キューで待機している USER2 を見つけます。プログラムは、USER1 に対して行ったのと同じ手順を USER2 に対しても実行し、converse ステートメントに到達してフォームを送信し、次にループバックしてもう一度メッセージ・キューを確認します。
  5. ここで、このプログラムは、converse ステートメントに対する USER1 の応答をほぼ見つけます。 EGL によって生成された制御ロジックは、この応答が USER1 の処理の続きであると判断し、以下を行います。
    • USER1 のデータ (converse ステートメントのロケーションを含む) を復元します。
    • 多数のシステム変数を更新します。
    • FORM1 が要求した妥当性検査をすべて実行します。
    • 入力エラーがないと想定して、converse ステートメントの後のステートメントで処理を再開します。
  6. 最後に、このプログラムは別の converse ステートメントに到達し、すべてのデータを保存して、USER1 に応答を送信します。次にプログラムは、ループバックしてメッセージ・キューを再度確認します。
  7. USER2 が外出しており、メッセージ・キューにはトランザクション・コード MYTRXCD1 に関連付けられているものが何も残されていないと想定します。プログラム MYTRXCD1 は終了します。
  8. 後で USER1 が最新のコンソール・メッセージに応答すると、IMS は、トランザクション・コード MYTRXCD1 に関連付けられているメッセージ・キューに再びメッセージを持つことになり、プログラム MYTRXCD1 を再度開始します。 EGL によって生成された制御ロジックは、この応答が USER1 の処理の続きであると判断し、すべてのデータを復元して処理を続行します。

フィードバック