IBM i 実行管理：バッチジョブ実行の流れ

5250端末からの [対話型ジョブの開始時フロー](https://qiita.com/gomAnomalocaris/items/3040e71ea79374de121c) は以前説明しました。今回はバッチジョブの開始時のフローについて説明します。

バッチジョブの開始方法は大きく３通りに分類されますが、最も一般的なジョブ投入コマンド **SBMJOBコマンド** でのフローについて説明します。
※3つの方法について知りたい方は当記事最後の **おまけ** を参照ください。

## バッチジョブコマンドの例
以下のコマンドを実行するとします。
```
SBMJOB CMD(CRTRPGPGM PGM(DEMOLIB/K201R) SRCFILE(DEMOLIB/QRPGSRC) SRCMBR(K201R)) 
 JOB(JOB1) 
 JOBD(QGPL/QDFTJOBD) 
 JOBQ(*JOBD) 
 USER(QPGMR) 
 INLLIBL(DEMOLIB)                  
```
※初心者向け上記コマンドの説明
|パラメーター|説明|
| --- | --- |
| CMD | SBMJOBで実行するコマンド。例ではRPGをコンパイル |
| JOB | SBMJOBで実行されるジョブ名をJOB1という名前にしています |
|JOBD | SBMJOBで実行するジョブが参照するジョブ記述名 |
| JOBQ | SBMJOBで投入するジョブ待ち行列名を指定。"JOBDなのでJOBDで指定したQDFTJOBDの指定を参照する |
| USER | 例ではRPGをコンパイルする際に使用されるユーザープロフィールがQPGMRになります(コンパイルしたPGMオブジェクトの所有者がQPGMRになる）|
|INLLIBL | コンパイルコマンドを実行する際に参照されるライブラリーリスト。K201Rが参照しているDSPF, PF,LF等のファイルがライブラリーリストのライブラリーに存在していないとコンパイルエラーになる |

## バッチジョブの実行フロー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/7a06f0c8-81be-7a13-5cdd-393e00b062ad.png)

## 1.バッチ用サブシステムの開始：STRSBSコマンド
サブシステム*SBS QSYS/QBATCHが開始された際、サブシステム記述のジョブ待ち行列に指定されたジョブ待ち行列 *JOBQがサブシステムに獲得される

## 2. バッチジョブを投入:SBMJOBコマンド実行
②のSBMJOBコマンドを実行します。
SBMJOBコマンドでJOBQ *JOBD が指定されているので、③のJOBD QDFTJOBD に定義されているジョブ待ち行列を参照します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/8706eb49-8846-9eb2-abb7-406af4cb56ff.png)
例ではQGPL/QBATCHI　JOBQに投入されます。このJOBQは①でSBS QBATCHに紐づいているのでバッチジョブはQBATCH 内で実行されます。

## 3. サブシステムに指定されている経路指定項目を参照
**③のJOBDには経路指定データがQCMDIと指定されています。** この経路指定データを④SBSD QBATCHの経路指定項目と突合せします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/5b75a41e-4110-3bfd-b866-54ea33438b58.png)

**④SBSD_QBATCHの経路指定項目を見ると下記のように、QCMDI は無いので、順序番号9999の比較値*ANY が JOBD指定のQCMDI と合致し、⑤QSYS/QCMDが実行されることになります。**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/c99d54aa-641a-5357-167d-1b79a9a185f4.png)

QCMDはSBMJOBコマンドで指定されたコマンド、⑥CRTRPGPGMコマンドを実行します。

## バッチジョブ実行結果の確認
SBMJOBコマンドで指定したパラメーターがどのように反映されたかを確認してみます。

### SBMJOBされたジョブ名
**WRKSBMJOBコマンド** を使用してSBMJOBしたコマンドの結果を確認します。
ジョブ名はJOB(JOBD1)が参照されたことが分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/8b1b6cbf-00ac-3f9b-4afd-e45829100672.png)

### コンパイルされたプログラムの所有者
DSPOBJD OBJ(DEMOLIB/K201R) OBJTYPE(*PGM) を実行してコンパイルされたオブジェクトの所有者を確認すると、USER(QPGMR)が参照され、所有者（コンパイル実行時のユーザー）がQPGMRになったことが分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/74acdefd-6be1-ea7c-106c-d7bb6aaf23ae.png)

## ジョブ待ち行列JOBQ の特徴
・ジョブ待ち行列に登録された（SBMJOBされた）ジョブは、ジョブ待ち行列を接続しているサブシステムSBSの開始によって実行される。
・1つのジョブ待ち行列は、同時に複数の活動中サブシステムに接続できない。
・ジョブ待ち行列にSBMJOBされたジョブは、待ち行列中でスケジュール優先順位の高い順に取り出されて実行される。スケジュール優先順位は最高:1～最低:9でSBMJOB時に指定（SBMJOB後CHGSBMJOBコマンドで変更も可）。
・スケジュール優先順位が同じジョブは、先入れ先出し(FI/FO：ファーストイン・ファーストアウト）で取り出されて処理される。
・実行されたジョブはジョブ待ち行列から削除される。



## ※おまけ：その他のバッチジョブ開始方法
（以下、あまり役立たないトリビアみたいなものです、、お暇な方はどうぞ^^;）

バッチジョブの定義の一つは、ジョブをジョブ待ち行列に投入して実行することです。ジョブをジョブ待ち行列に投入する最も一般的な方法は今回説明した **SBMJOBコマンド** を使用する事ですが、これ以外にも以下のような方法があります。

| 方法 | コマンド | 参考マニュアルページ |
|---|---|---|
|リーダーの使用|STRDBRDRコマンド, STRDKTRDRコマンド|https://www.ibm.com/docs/ja/i/7.4?topic=ssw_ibm_i_74/cl/strdbrdr.html |
|ジョブの投入|SBMJOBコマンド、SBMDBJOBコマンド, SBMDKTJOBコマンド| 
|ジョブの転送|TFRJOBコマンド, TFRBCHJOBコマンド | |

実は私も1つ目の方法を実行したことがなく、ちょっと調べてみたところ、1つ目は [入力スプーリング](https://www.ibm.com/docs/ja/i/7.3?topic=concepts-input-spooling) と呼ばれるようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/e846d27f-8281-40bd-892a-711a3d24c381.png)

上記マニュアルページの説明によると入力スプーリングのメリットとして下記の記述があります。

**入力ストリームが小さいジョブの場合は、入力スプーリングを使用しないことによって、システム・パフォーマンスの向上を図ることができる場合もあります。 ジョブ投入 (SBMJOB) コマンドで入力ストリームを読み取り、該当するサブシステムの中のジョブ待ち行列にジョブを入れ、スプーリング・サブシステムおよび読み取りプログラムの操作をバイパスします。**

**ジョブが大きい入力ストリームの読み取りを必要とする場合は、入力スプーリング (ディスケット読み取りプログラム開始 STRDKTRDR または STRDBRDR コマンド) を使用して、ジョブが実際に処理されるのとは別に独立してジョブをインポートできるようにすべきです。**

上記述から1つ目のリーダーの使用は1980年代以前のようなストレージ（HDD）（やCPU,メモリ）が非常に低速な時代においてスループット・処理速度を向上させるための方法だったのだと理解しました。この記事の元ネタとなっているAS/400発表時点の資料ではSBMJOBコマンドはリーダー読取り（1つ目の方法）よりも使用資源が少なく処理速度が速い、と記載されています。リーダーを使用したジョブ投入は現在必要性が無いのかもしれません。