スケジュール済み Apexとは
- Apex スケジューラーを使用すると、Apex クラスの実行を遅らせて、指定した日時に実行できる
- スケジューラーは、Apex 一括処理を使用した日次または週次のメンテナンス作業に最適
- スケジュール済み Apex ジョブは一度に 100 件しか設定できず、スケジュール済み Apex の 24 時間あたりの最大実行数も制限されている
- 同期 Web サービスコールアウトは、スケジュールされた Apex からは実行できない
- コールアウトを実行するには、@future(callout=true) のアノテーションを付加したメソッドにコールアウトを配置し、このメソッドをスケジュールされた Apex からコールすることで非同期コールアウトを実行する
- スケジュールされた Apex で一括処理ジョブを実行する場合、一括処理クラスからコールアウトを実行できる
構文
- クラスに
Schedulable
インターフェースを実装する
System.schedule
メソッドを使用して特定の時間に実行されるようにクラスのインスタンスをスケジュールする
- メソッドのパラメータは
SchedulableContext
オブジェクト
- クラスがスケジュールされると、スケジュール済みジョブを表す
CronTrigger
オブジェクトが作成される
CronTrigger
オブジェクトには、CronTrigger API オブジェクトの ID を返す getTriggerId
メソッドが存在する
global class SomeClass implements Schedulable {
global void execute(SchedulableContext ctx) {
}
}
サンプルコード
- Apex スケジューラー UI またはプログラムからcallが可能
global class RemindOpptyOwners implements Schedulable {
global void execute(SchedulableContext ctx) {
List<Opportunity> opptys = [SELECT Id, Name, OwnerId, CloseDate
FROM Opportunity
WHERE IsClosed = False AND
CloseDate < TODAY];
TaskUtils.remindOwners(opptys);
}
}
System.Schedule メソッドの使用
- ユーザーにクラスの実行権限があるかどうかにかかわらず、すべてのクラスが実行される
RemindOpptyOwners reminder = new RemindOpptyOwners();
String sch = '20 30 8 10 2 ?';
String jobID = System.schedule('Remind Opp Owners', sch, reminder);
UI からのジョブのスケジュール
- UIを使用してクラスをスケジュールすることも可能
- [設定] →[Apex クラス]
- [Apex をスケジュール] をクリック
- ジョブ名に「Daily Oppty Reminder」などと入力
- Apex クラスの横にあるルックアップボタンをクリックし、検索語に「*」と入力して、スケジュール可能なすべてのクラスのリストを取得
- 検索結果で、スケジュール済みクラスの名前をクリック
- [毎週] または [毎月] の頻度を選択して、必要な頻度を設定
- 開始日と終了日、適切な開始時刻を選択
- [保存] をクリック
サンプルテストクラス
System.schedule
メソッドの前後に startTest
と stopTest
を再度使用して、テストを続行する前に処理が終了するようにする
@isTest
private class RemindOppyOwnersTest {
public static String CRON_EXP = '0 0 0 15 3 ? 2022';
static testmethod void testScheduledJob() {
List<Opportunity> opptys = new List<Opportunity>();
Date closeDate = Date.today().addDays(-7);
for (Integer i=0; i<10; i++) {
Opportunity o = new Opportunity(
Name = 'Opportunity ' + i,
CloseDate = closeDate,
StageName = 'Prospecting'
);
opptys.add(o);
}
insert opptys;
Map<Id, Opportunity> opptyMap = new Map<Id, Opportunity>(opptys);
List<Id> opptyIds = new List<Id>(opptyMap.keySet());
Test.startTest();
String jobId = System.schedule('ScheduledApexTest',
CRON_EXP,
new RemindOpptyOwners());
List<Task> lt = [SELECT Id
FROM Task
WHERE WhatId IN :opptyIds];
System.assertEquals(0, lt.size(), 'Tasks exist before job has run');
Test.stopTest();
lt = [SELECT Id
FROM Task
WHERE WhatId IN :opptyIds];
System.assertEquals(opptyIds.size(),
lt.size(),
'Tasks were not created');
}
}