1. 導入:なぜSTATIC EXTERNALが重要なのか
大規模なメインフレームシステムでは、複数のプログラム(コンパイル単位)間で共通の制御データや定数テーブルを参照したい場面が多々あります。もし、これらのデータを個別のプログラム内にハードコーディングして保持すると、修正時にすべてのプログラムを再コンパイルする必要が生じ、保守コストが激増します。STATIC EXTERNAL属性を適切に利用することで、メモリ領域をリンカ(Binder)レベルで一元管理し、システム全体で整合性の取れたデータ共有を実現できます。
2. 基礎知識:STATIC EXTERNALの仕組み
STATIC EXTERNALとは、PL/Iなどの言語において「外部手続きを跨いで共有される静的メモリ領域」を指します。
通常の内部変数がそのプログラム内でのみ有効であるのに対し、EXTERNAL属性を付与された変数は、リンカによって「同じ名前を持つ領域」として結合されます。これにより、プログラムAで更新した値を、プログラムBで即座に参照することが可能になります。
3. 実装/解決策:定義と参照のルール
実装における重要なルールは、「定義」と「参照」の整合性です。
1. 共有したい領域を定義する側は、通常の宣言を行います。
2. その領域を参照する側は、BASED EXTERNALまたは単なるEXTERNALとして定義します。
3. リンカ(Binder)が、これら同じ名前のシンボルをメモリ上の同一アドレスとして解決します。
4. サンプルプログラム
以下のコードは、システムの設定情報を保持する共有ブロックの例です。
/ — 共有データを定義するプログラム — /
DCL 1 SYS_CONFIG_BLOCK STATIC EXTERNAL,
5 SYSTEM_ID CHAR(4), / システム識別子 /
5 MAX_RETRY FIXED BIN(15); / 最大リトライ回数 /
/ 初期化処理 /
SYSTEM_ID = ‘PROD’;
MAX_RETRY = 3;
/ — データを参照する別のプログラム — /
DCL 1 SYS_CONFIG_BLOCK BASED EXTERNAL,
5 SYSTEM_ID CHAR(4),
5 MAX_RETRY FIXED BIN(15);
/ 共有領域の値を参照 /
IF SYSTEM_ID = ‘PROD’ THEN
PUT SKIP LIST(‘現在のシステムは本番環境です。リトライ回数:’ || MAX_RETRY);
5. 応用・注意点:現場の落とし穴
現場で最も注意すべきは「スレッドセーフ」と「名前の衝突」です。
・同期化の考慮: 近年のCICS環境やバッチのマルチスレッド実行では、共有領域への同時アクセスが競合し、データの不整合を招く恐れがあります。ENQ/DEQマクロを用いた排他制御や、読み取り専用として運用するなどの設計が必須です。
・移行時の視点: Java等へ移行する場合、これらはSpring Frameworkの共通Bean(Singletonスコープ)に相当します。しかし、Java側ではグローバル変数の使用は避ける傾向にあるため、単なるデータ保持ではなく、DI(依存性の注入)を介したアクセサ経由のアクセスに書き換えるのがモダンな設計です。
古い技術と侮るなかれ、現代のアーキテクチャにおいても「共有状態」をどう管理するかという本質は変わりません。正しく理解して、堅牢なシステム構築を目指しましょう。

コメント