【PL/I学習|実務向け】PL/IにおけるON-Unitの再入可能性(Reentrancy)と無限ループの回避策

1. 導入

メインフレームのPL/I開発において、エラーハンドリングはシステムの堅牢性を左右する最重要項目です。特に例外処理(ON-Unit)を記述する際、「ハンドラの中でさらに例外が発生したらどうなるか?」を理解しておくことは不可欠です。本記事では、例外の連鎖による無限ループを防ぐためのPL/Iの保護機構と、安全なエラーリカバリ設計の考え方について解説します。

2. 基礎知識

PL/IのON-Unitは、指定したイベント(ERROR、CONVERSION、SUBSCRIPTRANGEなど)が発生した際に制御を奪う仕組みです。
ここで重要なのが「再入可能性」です。PL/Iはハンドラ実行中、同じ種類の例外に対するON-Unitを一時的に無効化します。これは、ハンドラ内で発生したエラーが再び同じハンドラを呼び出し、無限ループに陥るのを防ぐためのOSレベルの安全装置です。この間、システムはデフォルトの動作(通常はプログラムの強制終了)に切り替わります。

3. 実装/解決策

現場での実装においては、ON-Unitを「回復可能な処理」と「致命的な終了処理」に明確に分離する必要があります。
リカバリ処理を記述する際は、「このハンドラ自体がエラーを起こす可能性はないか?」を常に自問してください。もしハンドラ内で複雑なデータ操作やファイルアクセスを行う場合は、内部でさらなるブロックを設けるか、あるいはエラー発生時にログを出力して速やかに終了させる「セーフティ・パス」を設計することが推奨されます。

4. サンプルプログラム

以下は、ERRORハンドラ内での二重障害を制御する基本的なパターンです。

1
ERROR_DEMO: PROC OPTIONS(MAIN);

/ ERROR発生時のハンドラ定義 /
ON ERROR BEGIN;
/
このブロック内でさらにエラーが発生すると、
PL/Iは無限ループを防ぐため、このON-Unitを一時無効化し
システムデフォルト(アベンド)へ移行します。
/
PUT SKIP LIST(‘エラーを検知しました。リカバリを試みます…’);

/ リカバリ処理の開始 /
/ ここでファイルI/Oや計算を行うとエラー再発リスクがある /
CALL RECOVERY_ROUTINE;

PUT SKIP LIST(‘リカバリ完了。処理を継続します。’);
END;

/ 意図的に例外を発生させるコード /
SIGNAL ERROR;

RECOVERY_ROUTINE: PROC;
/ リカバリ中に万が一エラーが起きると、即座にアベンドする /
PUT SKIP LIST(‘リカバリ処理を実行中…’);
END RECOVERY_ROUTINE;

END ERROR_DEMO;

5. 応用・注意点

現場で陥りやすいバグとして、「REVERT文」の使い忘れがあります。ON-Unit内での処理が完了した際、状況に応じてREVERTを用いてハンドラを元の状態に戻さないと、意図しないタイミングでエラーが捕捉され続ける可能性があります。

また、現代の言語(JavaやC#など)のtry-catch-finally構造と異なり、PL/IのON-Unitは実行フローを「動的」に制御します。そのため、複雑なロジックをハンドラ内に詰め込むのは禁物です。二重障害が発生した際には、無理にプログラムを続行しようとせず、「ログを確実にフラッシュ(出力)して、安全にアベンドさせる」設計こそが、メインフレームにおける最も信頼性の高いエラーリカバリ戦略となります。

コメント

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