「暗黙のアクセス・パス共有」でプログラムがループ?!

ここ最近、何回か「暗黙のアクセスパス共有」について聞かれたことがありました。

ちょっと見てみたら「アクセス・パスが暗黙共用されることによってプログラムの動作に影響を与えることがあります」なんていうお知らせが出てたりしますし、もしかして今ドキの人はこういう事象・考慮点のことを知らないのかな? とちょっと心配になりました。

畑村洋太郎の「失敗は伝わらない」ではないですが、S/38 の頃ではわりあい知ってて当り前だったことがなかなか「伝わ」っていないんですね。。
これがけっこう昔からある事象なのは昔から有名な AS/400 のサイト関連記事があることからもわかると思います。

今さらですが、どんな事象が起きるのか、どうやって直すのか、できるだけ具体的にシンプルなケースで見ていきましょう。


よくある事象その1

よくあるのは↑のリンク先の記事にもあるように、ループでしょうね。

どんなときに、どんなふうになると起きるのか、順を追って見ていきましょう。

物理ファイル/論理ファイル/プログラムの説明

今回の例で使用する物理ファイルです。
キーは K1 についてます。

ソースは↓です。

     A          R REC                                                           
     A            K1            10                                              
     A            K2            10                                              
     A            K3            10  0                                           
     A          K K1                                                            

プログラムは、フィールド K2 を 2つめのキーとして追加した論理ファイルを読み込んで処理します。

     A          R REC                       PFILE(PF)                           
     A          K K1                                                            
     A          K K2                                                            

普通に論理ファイルとしてコンパイルして使用します。特別なオプションなどがあるわけではありません。
ちなみにライブラリー名の "INPACC" の "INP" は Implicit のつもりが n になってしまったものです。。時間がなかったのでそのまま使っています。

3つめのフィールドに 100 足す、というだけのカンタンなプログラムです。
わかりやすいように簡単にしましたが、とはいうものの、そんなに現実性のないものでは実はありません。日付を進めるとか、税などで何% か足すといった処理を模したものですね。

     FLFK2    UF  E           K        DISK                                     
      *                                                                         
     C           KLIST1    KLIST                                                
     C                     KFLD           F1     10                             
     C                     KFLD           F2     10                             
      *                                                                         
     C                     MOVEL'1'       F1                                    
     C                     MOVEL'1'       F2                                    
      *                                                                         
     C           KLIST1    SETLLREC                                             
      *                                                                         
     C           *IN91     DOWEQ'0'                                             
     C                     READEREC                      10                     
     C           *IN10     IFEQ '0'                                             
     C                     ADD  100       K3                                    
     C                     UPDATREC                                             
     C                     ELSE                                                 
     C                     MOVE '1'       *IN91                                 
     C                     ENDIF                                                
     C                     ENDDO                                                
      *                                                                         
     C                     SETON                         LR                     
     C                     RETRN                                                

(当然ですが)ちゃんと動きます。

その後、都合でキーを追加した新しい LF を作った、としましょう。

     A          R REC                       PFILE(PF)                           
     A          K K1                                                            
     A          K K2                                                            
     A          K K3                                                            

論理ファイルを追加するのは、↑で言ったようにこのフィールドが日付だったとしても、金額などだったとしても、そんなに現実性のない処理ではありません。
SQL でいう ORDER BY に相当する処理は LF の K で行うことはめずらしくありません。
(というか逆に、RPG でプログラムの中でソートしたりするのはそんなに一般的なことではないでしょう。S/3 とか S/36 から移行したプログラム以外で見たことはありませんね)
ほとんどプログラム毎に専用の論理ファイルが作られているようなケースも、それほどめずらしくないでしょう。

論理ファイルを使わないと、それはそれで得てしてレコードを全件読み込んでしまうような処理になってしまいます。データが増えるにつれて処理時間が延びる一方、というようなプログラムになってしまうので問題はあるんですよねぇ。

今回プログラムで読み込んでいる LFK2 のファイル記述を DSPFD コマンドで見てみましょう。

「キー・フィールド」は 2つ、ですね。
「暗黙のアクセス・パスの共有」も "NO" です。

再度プログラムを動かしてみます。

ちゃんと動きます。

暗黙のアクセス・パス共有で起きること

さてここからが事象の説明になります。

RPG で参照している LFK2 を削除してみます。

削除して、あらためて CRTLF をしたうえでファイル属性を見てみましょう。

すると、↓のように「キー・フィールド」は 3つになり、「暗黙のアクセス・パスの共有」が "YES" に変わっていることがわかります。
「アクセス・パス所有ファイル」は "LFK3" になっているのもわかりますね。

つまり、さきほどのプログラムで読み込んでいる論理ファイルは「暗黙のアクセス・パスの共有」が行われているようになっています。

この状態でプログラムを再度実行してみましょう。

… いつまでたっても終わりません … 強制キャンセルをして、結果のファイルを見てみると。。。 K3 の値がいったい何回 100 足されたのかわからないくらいになっています。(ま、100 で割ればわかりますが)
2レコードまでと 3レコード目で値が異なっているのは、ちょうどこのあいだで強制キャンセルが効いたということだと考えられます。

ちなみに、レベルチェックしてあろうがなかろうが結果は一緒です。

↑の状態で LFK3 を削除してみましょう。
「アクセスパス所有ファイル」を削除することになるわけですが、どうなるんでしょうか??

LFK2 のファイル属性を見てみましょう。

LFK3 を削除しても「キー・フィールド」は 3つのままです。
「暗黙のアクセス・パスの共有」は "NO" に、「アクセス・パス所有ファイル」も項目ごとなくなった、というのに。。

もちろんこの状態でも(キーは実質 3つあるわけですから)問題は起きます。つまりプログラムはループします。

ここで再度 LFK3 を作成してみるとどうなるでしょうか?

「アクセス・パス所有ファイル」は … キーは本来 2つしかないはずの LFK2 になります。
(もちろんこの状態でも問題は起こったままです)

こうなってしまうとけっこう大変ですね。もはや何が本来正しいのか判別するのにはソースとつきあわせるしかありません。

多少人工的な事例に見えるかもしれませんが、移行などに伴うライブラリーの復元とか、オブジェクトの損傷などによる再作成などで、似たようなことが起きる可能性はないわけではありません。
先述しましたが、論理ファイルが大量に存在しているのはそんなにめずらしいことではありませんし、多ければ多いほどこうしたことが起きる確率は多くなるわけです。

実は、起きる事象はこれだけではありません。

そちらは「よくある事象その2」にまとめましたので、見てみてください。


解決方法の概略

さて、どうやって直すか、ですが。

ソースがあれば、全部順番にリコンパイルするのが確実ではあります。
正しくなっているかどうかは DSPFD コマンドで確認できますので、確認しながら作成し直す、というのがひとつの手です。

実際には、移行プロジェクトなんかでもこの事象は起きるわけで(実際関連記事のケースでは「データベースの移行」の時に遭遇してしまったようですね)、今どきのくくりで言うと「インフラ」の領域で起きるわけです。

そういう「移行」の時にどれが正しいソースかがすでにアヤしくなっているというのもよくある話なので、現状オブジェクトベースでなんとかする方法が必要になることがよくあります。
で、これを直すには必ずしもソースが常に必要になるわけでもないんです。

ただし、「移行」以前の状態はあらかじめきちんと取っておかないとわかりません。オブジェクトのバックアップがあったって、オブジェクト同士の関係はわかるわけではありません。
もし、こうした問題が起き得る環境(日付や金額などを並べ替えのためにキー指定した論理ファイルが存在する/そんな論理ファイルを利用した RPG がたくさんある/論理ファイル経由の更新がけっこうある etc... )なのであれば、事前に DSPFD コマンドで重要な属性がどうなっているかを、オブジェクトの保管そのものとは別に取得しておく必要があります。

リクツ

この「暗黙的アクセス・パス共有」は論理ファイルの作成順で起きる事象になります。

アクセス・パスの作成というのはいつ行われるものなのか? というと、CRTLF 時だけではなく RSTLIB/RSTOBJ 時にも行われるものなんですね。
ということは、作成する順番だけでなく、復元する順番ででもこの「暗黙的共有」は制御できるわけです。

逆に言えば、RSTLIB などでの論理ファイルの復元される順番によって、今までとは異なる「暗黙的アクセス・パス共有」が起きてしまう可能性もある、ということでもあります。
もし起こってしまったら、↑で言ったようにきちんと事前の情報を DSPFD コマンドで取得しておかないとまったく対処はできません。↑で言ったような「こうした問題が起き得る環境」では最悪の場合、プログラムの仕様の解読と書き直し、という羽目になる可能性があります。(これが発覚した時にそんな余裕があるかどうか知りませんが、、)

今回は、事前の取得情報がある、という前提で以下の話をします。

対処方法は実はカンタンで、現状のアクセス・パスをいったん保管して、正しい順番で復元し直せばいいだけです。

"RSTLIB → 今までの状態との比較・確認 → 問題のあったものを削除して再復元" といったような流れになるわけですね。
復元元はテープでもいいですし、問題があるものだけを SAVF などに SAVOBJ し直して使うという手もあるでしょう。

保管ファイルの作成

今回は前の状態がわかっています。
対象となっている 2つの論理ファイルについて、「暗黙のアクセス・パスの共有」が NO 、「アクセス・パス所有ファイル」が空欄になっているということが DSPFD などで確認できれば OK ということになりますね。

まず、保管ファイルを作成します。

論理ファイルの保管

現在のアクセス・パスはそのまま保管して使用できます。
アクセス・パスは RSTOBJ 時にも再作成されますので、きちんと順番を守って復元すればいいわけです。

関係するすべての論理ファイルの削除

LFK2 と LFK3 を削除します。

暗黙的な共有がされてしまうと問題が起きる論理ファイルの復元

LFK2 を最初に復元します。

「暗黙のアクセス・パスの共有」は NO、「アクセス・パス所有ファイル」は空欄になっていることが確認できますね。

先に復元すると共有を行ってしまう論理ファイルの復元

続けて LFK3 を復元してみましょう。

LFK3 も「暗黙のアクセス・パスの共有」が NO になっていることがわかりますね。

ツール化もしくは/および今後の改善案

人間でないと判断できないようなロジックはないので、こうした手順はプログラム化可能ですね。
事前にとっておいた情報と比較して、保管 → 削除 → 正しい順番で復元、という至極単純なフローなので、今回はプログラム例などは載せないことにします。

今回起きている事象ですが、「論理ファイル」という旧態依然としたものを使っている以上、これは仕方のないことです。まったく仕様どおりの動きですし、数十年間変わっていないわけです。
移行の機会に SQL化するとか、OPNQRYFに書き換えるとか、考えてみてはいかがでしょう。

[Top Pageに戻る]

Ads by TOK2