tyoshikawa1106のブログ

- Force.com Developer Blog -

SFDC:一年後に実行するスケジュールバッチの登録方法

Apexバッチのスケジュール登録は週または月単位となっています。そのためバッチを一年後にスケジュール登録したい場合は別の方法を検討する必要があります。

f:id:tyoshikawa1106:20151229194850p:plain


Apexでは『System.schedule』をつかってスケジュールバッチの登録ができます。これは一年後の日付でも登録が可能です。

f:id:tyoshikawa1106:20151229195720p:plain

private void doNextBatchSchedule(String nextBatchName, Date targetDate) {
    ApexSampleScheduler cls = new ApexSampleScheduler();
    String sch = '0 0 1 1 JAN ? ' + String.valueOf(targetDate.year());
    System.schedule(nextBatchName, sch, cls);
}

日時の登録は左から秒・分・時・日・月・曜日・年と指定できます。月には「JAN」や「FEB」などの特殊文字をつかった指定が可能です。?は特定の値を指定しない場合の特殊文字です。


System.scheduleの詳細はこちらです。


System.shceduleをつかって次のバッチをスケジュール登録するとApexバッチ実行後に次のバッチがキュー登録されています。
f:id:tyoshikawa1106:20151229200851p:plain


スケジュール済みジョブを確認すると2015年の一年後、2016年がスケジュール登録されます。
f:id:tyoshikawa1106:20151229201005p:plain

System.scheduleの注意点

Apexクラスをスケジュール登録するとき、ジョブ名が登録済みの場合、エラーとなります。
f:id:tyoshikawa1106:20151229201624p:plain


運用でバッチを2回起動することは無いので大丈夫。と対応する方法も考えられますが、その対応をするとテストクラスで残念な結果が待っています。
f:id:tyoshikawa1106:20151229201953p:plain


このエラーを解決するためにも、既にスケジュール登録済みの場合は登録処理をスキップするようにしておくと安全だと思います。スケジュール登録済みのジョブ情報は『CronJobDetail』オブジェクトにクエリを実行して取得可能です。

SELECT Id, Name, JobType FROM CronJobDetail

f:id:tyoshikawa1106:20151229203058p:plain


ジョブ名を条件にスケジュール登録件数を取得して、1件以上の場合は登録処理をスキップする方法で対応できると思います。
f:id:tyoshikawa1106:20151229203530p:plain

※ビジネスロジック部分は別クラスに実装する方が保守しやすくなると思いますが、別クラスに分けたくない、publicメソッドにしたくない場合は@TestVisibleを宣言してテストクラスから呼び出せるようにしておくとテストがしやすくなります。


スケジュールの重複登録エラーはこんな感じで回避できます。


CronJobDetailオブジェクトの詳細はこちらで確認できます。

サンプルコード

一年後に実行するスケジュールを登録する処理のサンプルです。

関連記事

スケジュールバッチに関する記事です。