メインフレームの残響:ON CONVERSIONで守る、基幹システムの「最後の砦」
夜中の3時、運用担当者からの突然の電話。「オンラインバッチがS0C7で落ちました」。
システムアーキテクトとして、この言葉ほど心臓を締め付ける響きはない。特にメインフレームのPL/I環境において、数値変換の失敗は単なるデータエラーではなく、DB2やCICS、あるいは広大なレガシーコードの海に潜む「見えない地雷」だ。
今日は、PL/Iにおける`ON CONVERSION`を用いたエラーハンドリングの本質と、それが現代のマイグレーションプロジェクトにおいてどれほどの「防波堤」になり得るかについて、少し深掘りして話そうと思う。
—
なぜ、今さらON CONVERSIONなのか
現代のJavaやC#の堅牢な型システムに慣れたエンジニアにとって、PL/Iの「暗黙の型変換」は狂気と映るかもしれない。しかし、汎用機の世界では、COBOLの`PIC X`で定義された入力データが、平然と`DECIMAL FIXED`として演算に放り込まれる。
ここで発生するのが、かの有名なデータ例外(S0C7)だ。だが、現場の猛者は知っている。「落ちるプログラムは設計の敗北」であり、適切に`ON CONVERSION`を実装していれば、バッチは停止せず、エラーログを吐き出して優雅に次のレコードへと遷移できるのだ。
実践:ON CONVERSIONによるデータ救済の設計
以下に、実務で使える堅牢なパターンを示す。
1
/
- 構造化されたエラーハンドラの実装例
- 変換不能データに遭遇した際、ABENDを回避しログを残す
/
PROCEDURE_MAIN: PROCEDURE OPTIONS(MAIN);
DCL WS_INPUT_CHAR CHAR(10) INIT(‘123A5’); / 不正データ /
DCL WS_NUM FIXED DEC(5,0);
/ ONユニットの定義:変換エラーを捕捉 /
ON CONVERSION BEGIN;
/ 発生したフィールドの特定とログ出力 /
PUT SKIP LIST(‘データ変換エラー発生: ‘ || ONCHAR());
/ 不正な値のまま処理を継続せず、0で初期化してリトライさせる等の制御 /
WS_NUM = 0;
/ エラーを無視して処理を続行させるための指示 /
REVERT CONVERSION;
END;
/ ここで変換が発生する /
WS_NUM = WS_INPUT_CHAR;
PUT SKIP LIST(‘処理後の数値: ‘ || WS_NUM);
END PROCEDURE_MAIN;
このコードの肝は、`REVERT`による復帰と、`ONCHAR()`で異常値を即座に特定する戦略にある。これをCICSのトランザクション内で実装すれば、ユーザー画面に「システムエラー」という絶望を表示させず、「入力データを確認してください」という誠実なメッセージを返すことが可能になる。
—
アーキテクトの視点:マイグレーションの「落とし穴」
現在、多くの案件でメインフレームからJava/C#への移行が進んでいる。しかし、PL/IからJavaへ移行する際、最も恐ろしいのは「PL/Iコンパイラの暗黙の挙動をJavaの例外処理で完璧に再現できないこと」だ。
1. パックデシマル(COMP-3)の符号問題
PL/Iの`FIXED DECIMAL`は内部的にパックデシマルで保持される。移行先で単なる`BigDecimal`や`Long`にキャストすると、符号ビット(X’C’やX’D’)の不整合で即座にデータ不整合が起きる。特に、古いデータセットに紛れ込んだ「符号なしの正数」や「無効な符号ビット」を、Javaの`NumberFormatException`がどう解釈するか。ここを詰めずに移行すれば、本番環境で地獄を見る。
2. ポインタ操作と動的メモリの呪縛
PL/Iでは`BASED`変数とポインタを駆使してメモリを直接叩くことが日常茶飯事だ。CICSでの複雑な通信エリア(COMMAREA)の切り出しを、ポインタのオフセット計算で行っている場合、これをJavaのオブジェクトマッピングに置き換える作業は、単なるコード書き換えではなく、メモリの解釈学そのものだ。
3. ダンプ解析の哲学
S0C7が発生した際、あなたはメインフレームのダンプリーダを読み解くことができるか?
コンパイラオプションの`OPTIMIZE(2)`や`TEST`を指定した際のコード生成の違いを理解しているか?
最適化によって変数のアドレスがレジスタに退避された場合、ダンプ上の値とソースコードの期待値は一致しない。この「コンパイラが作り出した迷宮」を解く鍵は、常に`ON CONVERSION`のような例外ハンドラの積み重ねにある。
—
最後に:エンジニアとしての矜持
レガシー移行は、単なる「コードの移設」ではない。それは、先人が数十年間かけて守り抜いてきた「ビジネスルールの精緻な言語化」という作業だ。
PL/Iの`ON CONVERSION`を記述することは、エラーを隠蔽することではなく、「何が起きてもシステムがどう振る舞うべきか」というビジネスの意思をコードに刻むことに他ならない。
次にあなたがマイグレーション設計図を描くとき、あるいは夜中にバッチのログを追いかけるとき、この「エラーハンドリングの哲学」を思い出してほしい。コードは語る。どんなに古びた汎用機であっても、そこには確実に、我々が守るべき論理が存在しているのだから。
