概要
SalesforceではAPEXバッチ処理をスケジュール出来る上限が100件までと決まっている。
似たような処理や依存性のある処理を登録していると意外に上限まで行ってしまう。
そこで、バッチ処理を連結させてスケジューリング枠を減らす方法を考えてみた。
まあ、普通は100件行く前にリファクタや処理を見直すのが正しい施策とは思うが・・・
早速やってみた
public class hogeBatch implements Database.Batchable<sObject>, Schedulable {
public void start() {
~略~
}
public void finish(Database.BatchableContext BC) {
ChainSettings__mdt cs = [select batchNames__c from ChainSettings__mdt where DeveloperName = 'hogehoge'][0];
List<String> names = cs. batchNames__c;
String nextBatchName = '';
for (Integer i = 0; i < names.size(); i++) {
String batchName = names.get(i);
if (batchName == this.class.getName()) {
if (names.size() > (i + 1)) {
nextBatchName = names.get(i + 1);
}
}
}
if (String.isNotEmpty(nextBatchName)) {
if (Test.isRunningTest()) return; // Testクラス実行時は稼働させない
Batchable nextBatch = Type.forName(nextBatchName).newInstance();
Database.executeBatch(nextBatch, 200);
}
}
こんな感じ。
この処理で肝となるのは、「カスタムメタデータ型のリストを使う」点です。
カスタムメタデータ型の使い方などはこちらをどうぞ
カスタムメタデータ型の設定
まずは 設定 > カスタムメタデータ型 > 新規作成で適当に作成
カスタム項目を作成する
レコードを作成
以上
まとめ
この方法を使うことで、以下のメリットが得られます
- SF上のスケジュール数を抑えることが出来るので、より多くのバッチ処理を稼働させられる
- チェーン化したいバッチが増減した時、カスタムメタデータの値を変更するだけで済む(Apex修正不要)
- updateやdeleteなど、処理タイプごとにチェーン対象をレコードで切り分けられる
など。
まぁ、バッチの並行稼働数や一日の稼働上限なども設けられているため、無制限に増やすことは出来ないが、
スケジュール時に「この時間帯が埋まって新規登録出来ない!」が無くなるのは大きな利点かな。
1つ1つのバッチ時間が意外と短かったりすると、無駄なスケジューリングバッファ取られることになるからね。。。