【入門編】CICSにおけるEXEC CICS READ/WRITE/REWRITE/DELETEのVSAM操作 – PL/Iの基本構文とデータ制御実践ガイド

こんにちは!IBMメインフレームの世界へようこそ。
JavaやCOBOLでの開発経験がおありの方なら、新しい言語を学ぶときのワクワク感と、「レガシーシステムってなんだか黒魔術っぽくて怖いな……」という少しの緊張感が入り交じっている頃ではないでしょうか。

特に「PL/I(ピーエルアイ)」という名前を聞くと、なんだか古めかしくて難解な呪文のような印象を受けるかもしれません。でも、安心してくださいね。基本の考え方を掴んでしまえば、PL/Iは非常に表現力豊かで、エンジニアの意図を素直に聞いてくれる可愛い奴です。

今回は、そんなPL/Iとメインフレームのオンライン制御プログラム(CICS)を組み合わせて、VSAM(ヴィザム)という強力なデータストレージを操作する方法を、優しく紐解いていきましょう。

—

1. まずはリラックス!PL/Iの「予約語がない」という驚きの特権

他の言語(JavaやCOBOLなど)を触ってきた人にとって、一番度肝を抜かれるPL/Iの仕様がこれです。

「PL/Iには、いわゆる厳密な『予約語』が存在しない」

COBOLやJavaでは、`READ`や`WRITE`、`DATA`といった単語を勝手変数名に使えない(予約されている)ですよね。でも、PL/Iは文脈(コンテキスト)で判断してくれる懐の深い言語です。
例えば、極端な話、`READ`という名前の変数を宣言して、その直後にファイルの読み込みを行うコマンドを書いたとしても、コンパイラは「あ、ここは変数ね」「こっちは命令ね」と賢く空気を読んで解釈してくれます。

とはいえ、実務の現場で `READ` という変数を作るのは、自分の首を絞めるようなものなので絶対にやめましょう(笑)。ただ、「言語にガチガチに縛られない、自由度の高い世界なんだな」と気楽に捉えてもらえると嬉しいです。

—

2. CICSとVSAMの基本:CRUD操作の全体像

オンライン画面の裏側で、ユーザーが入力したデータを瞬時に保存したり、参照したりする仕組み。それがCICS(シス)とVSAMのコンビネーションです。

Javaで言うところのJPA/Hibernateや、JDBCによるデータベース操作のようなものだとイメージしてください。CICSでは、ファイル(VSAMデータセット)に対して以下の4つの基本操作(CRUD)を行います。

  • READ (参照): キーを指定してデータを1件読み込む
  • WRITE(作成): 新しいデータを1件追加する
  • REWRITE(更新): 読み込んだ既存データを書き換える
  • DELETE(削除): データを1件削除する

ここで、他の言語経験者が最もハマりやすいポイントをお伝えします。
CICSのファイル操作コマンド(`EXEC CICS …`)を実行すると、データベースの行ロック(排他制御)が自動的にかかるようになっています。Javaのトランザクション管理でわざわざ `SELECT … FOR UPDATE` を書く手間が、CICSではコマンド一つで裏側ですべて面倒を見てくれるのです。

—

3. 実践!PL/Iで書くCICS VSAM操作コード

百聞は一見に如かず。実際にCICS環境で動くPL/Iのサンプルコードを見てみましょう。
今回は、社員番号(EMP-ID)をキーにしてVSAMファイルからデータを読み込み、内容を書き換えて保存する一連の流れ(READ & REWRITE)を書いてみました。

—————————————————————-

  • CICS VSAM CRUD操作サンプルプログラム

—————————————————————-
SAMPLE_CICS_CRUD: PROC OPTIONS(MAIN);

/——————————————————–/
/ 1. ワーキングストレージ(データ定義)領域 /
/——————————————————–/
DCL WS-EMP-ID CHAR(5) INIT(‘12345’); / 検索キー /
DCL WS-RC FIXED BIN(31) INIT(0); / 応答コード/

/ VSAMファイルのレコードレイアウト(通称:DCL) /
DCL 1 EMP-RECORD,
5 EMP-ID CHAR(5), / 社員ID /
5 EMP-NAME CHAR(20), / 氏名 /
5 EMP-SALARY FIXED BIN(31); / 給与 /

/——————————————————–/
/ 2. VSAMファイルの読み込み(READ) /
/——————————————————–/
EXEC CICS READ
DATASET(‘EMPFILE’) / 対象のVSAMファイル名 /
INTO(EMP-RECORD) / 格納先の変数 /
RIDFLD(WS-EMP-ID) / 検索キー /
LENGTH(LENGTH(EMP-RECORD)) / レコード長 /
UPDATE / 排他ロックを取得! /
NOHANDLE; / エラー制御は自前でやる /

/ 応答コード(RESP)のチェック /
EXEC CICS ASSIGN(WS-RC) RESP;

IF WS-RC ^= DFHRESP(NORMAL) THEN DO;
/ データが見つからなかった場合などのエラー処理 /
/ ここで画面にメッセージを出力するなどの処理が入ります /
GOTO ERROR_ROUTINE;
END;

/——————————————————–/
/ 3. データの加工(給与をアップしてみる) /
/——————————————————–/
EMP-SALARY = EMP-SALARY + 50000;

/——————————————————–/
/ 4. VSAMファイルの更新書き込み(REWRITE) /
/——————————————————–/
EXEC CICS REWRITE
DATASET(‘EMPFILE’)
FROM(EMP-RECORD)
LENGTH(LENGTH(EMP-RECORD))
NOHANDLE;

/ 再びRESPをチェックして正常終了を確認 /
EXEC CICS ASSIGN(WS-RC) RESP;
IF WS-RC ^= DFHRESP(NORMAL) THEN DO;
GOTO ERROR_ROUTINE;
END;

RETURN;

ERROR_ROUTINE:
/ エラー時の共通処理(アボートやロールバックなど) /
EXEC CICS SYNCPOINT ROLLBACK;
RETURN;

END SAMPLE_CICS_CRUD;

—

4. コードの裏側で何が起きている?(排他制御の罠と注意点)

先ほどのコードの中で、最も重要なキーワードに気づきましたか?
そうです、`READ` コマンドの中にこっそり書いた `UPDATE` というオプションです。

EXEC CICS READ
…
UPDATE / ←ここが超重要! /
…

排他制御(ENQ/DEQ)の自動適用範囲

CICSにおいて、`UPDATE` オプション付きで `READ` を実行すると、CICSはそのレコード(またはコントロールベルト)に対して排他ロック(Exclusive Lock)を自動的にかけます。
これにより、他のユーザーが同時に同じデータを書き換えてデータが壊れてしまう(ロストアップデート)を防いでいるのです。

そして、このロックがいつ解除されるかが、CICSプログラミングの肝になります。
ロックは以下のいずれかのタイミングで自動的に解放(DEQ)されます。
1. `REWRITE` または `DELETE` コマンドが正常に実行されたとき
2. `UNLOCK` コマンドが明示的に実行されたとき
3. タスクが終了(RETURN)したとき、または `SYNCPOINT`(コミット)が発行されたとき

もし、`UPDATE` 付きで `READ` したのに、処理をミスって `REWRITE` も `UNLOCK` もせずに放置したまま画面に返してしまうと……、他の人がそのデータを永遠に触れなくなってしまう「デッドロック/リソースホルダー状態」を引き起こしてしまいます。実務では先輩から「ちゃんと後始末しなさい!」とこってり怒られるポイントなので、必ず覚えておいてくださいね。

—

さいごに

レガシーなシステムの世界も、一歩ずつ分解して見ていけば、現代のWebアプリケーション Architecture と本質的な考え方はまったく同じです。
「データを安全に取得し、ロックを制御し、安全に書き戻す」。

PL/Iの独特な見た目や、CICSの少しクセのある構文に最初は戸惑うかもしれませんが、怖がる必要はまったくありません。あなたのこれまでのプログラミング経験のベースがあれば、必ずすぐに手に馴染むようになりますよ。

今日の解説が、あなたのメインフレームライフの第一歩を少しでも明るく照らせたなら幸いです。それでは、次回のレガシー探訪もお楽しみに!

タイトルとURLをコピーしました