キュー可能 Apex
大規模なデータベース操作や外部 Web サービスのコールアウトなど、実行に長時間かかる Apex プロセスの場合、Queueable インターフェースを実装し、ジョブを Apex ジョブキューに追加することでそれらのプロセスを非同期に実行できます。この場合、非同期 Apex ジョブは、それ自身のスレッドのバックグラウンドで実行され、メインの Apex ロジックの実行を遅延させることはありません。キュー内にある各ジョブは、システムリソースが使用可能になると実行されます。Queueable インターフェースメソッドを使用するメリットは、ヒープサイズ制限など一部のガバナ制限値が、同期 Apex の場合よりも緩和される点にあります。
- ジョブ ID の取得: System.enqueueJob メソッドを呼び出してジョブを送信すると、メソッドは新しいジョブの ID を返します。この ID は AsyncApexJob レコードの ID に対応します。この ID を使用して、Salesforce ユーザインターフェースの [Apex ジョブ] ページから、またはプログラムで AsyncApexJob のレコードを照会する方法で、ジョブを識別してその進行状況を監視できます。
- 非プリミティブ型の使用: キュー可能クラスには、sObject 型やカスタム Apex 型など、非プリミティブデータ型のメンバー変数を含めることができます。これらのオブジェクトには、ジョブの実行時にアクセスできます。
- ジョブのチェーニング: 実行中のジョブから 2 つ目のジョブを開始することで、2 つのジョブを連鎖的に実行することができます。ジョブのチェーニングは、別の先行プロセスに依存する処理を実行する必要がある場合に便利です。
例
1public class AsyncExecutionExample implements Queueable {
2 public void execute(QueueableContext context) {
3 Account a = new Account(Name='Acme',Phone='(415) 555-1212');
4 insert a;
5 }
6}1ID jobID = System.enqueueJob(new AsyncExecutionExample());キュー可能クラスを実行のために送信すると、ジョブはキューに追加され、システムリソースが使用可能になると処理されます。ジョブの状況を監視するには、プログラムで AsyncApexJob を照会するか、ユーザインターフェースの [設定] から、[クイック検索] ボックスに「Apex ジョブ」と入力して [Apex ジョブ] を選択します。
送信したジョブに関する情報を照会するには、System.enqueueJob メソッドが返したジョブ ID で絞り込んで AsyncApexJob に対する SOQL クエリを実行します。次の例では、前の例で取得された jobID 変数を使用します。
1AsyncApexJob jobInfo = [SELECT Status,NumberOfErrors FROM AsyncApexJob WHERE Id=:jobID];future ジョブと同様、キュー可能ジョブはバッチを処理しません。そのため、処理されたバッチ数と合計バッチ数は常に 0 です。
キュー可能ジョブのテスト
1@isTest
2public class AsyncExecutionExampleTest {
3 static testmethod void test1() {
4 // startTest/stopTest block to force async processes
5 // to run in the test.
6 Test.startTest();
7 System.enqueueJob(new AsyncExecutionExample());
8 Test.stopTest();
9
10 // Validate that the job has run
11 // by verifying that the record was created.
12 // This query returns only the account created in test context by the
13 // Queueable class method.
14 Account acct = [SELECT Name,Phone FROM Account WHERE Name='Acme' LIMIT 1];
15 System.assertNotEquals(null, acct);
16 System.assertEquals('(415) 555-1212', acct.Phone);
17 }
18}ジョブのチェーニング
最初に別のジョブで他の処理を実行した後にジョブを実行する必要がある場合、キュー可能ジョブをチェーニングできます。ジョブを別のジョブにチェーニングするには、キュー可能クラスの execute() メソッドから 2 つ目のジョブを送信します。実行中のジョブから追加できるジョブは 1 つのみです。つまり、親ジョブごとに 1 つの子ジョブしか存在できません。たとえば、2 つ目のクラスが Queueable インターフェースを実装する SecondJob という名前である場合、このクラスを execute() メソッドのキューに次のように追加できます。
1public class AsyncExecutionExample implements Queueable {
2 public void execute(QueueableContext context) {
3 // Your processing logic here
4
5 // Chain this job to next job by submitting the next job
6 System.enqueueJob(new SecondJob());
7 }
8}Apex テストでは、キュー可能ジョブをチェーニングできません。チェーニングするとエラーになります。エラーを回避するには、ジョブをチェーニングする前に Test.isRunningTest() をコールして、Apex がテストコンテキストで実行されているかどうかチェックします。
キュー可能 Apex の制限
- キュー内のジョブの実行は、非同期 Apex メソッド実行の共有制限値に対して 1 回カウントされます。
- 1 つのトランザクションで System.enqueueJob を使用してキューに追加できるのは、最大 50 ジョブです。あるトランザクションで追加されたキュー可能ジョブの数を確認するには、Limits.getQueueableJobs() をコールします。
- チェーニングされたジョブの深度に制限はありません。つまり、1 つのジョブから別のジョブにチェーニングし、このプロセスを新しい子ジョブごとに繰り返して新しい子ジョブにリンクできます。Developer Edition 組織およびトライアル組織の場合、チェーニングされたジョブの最大スタック深度は 5 です。つまり、ジョブのチェーニングを 4 回行うことができ、チェーン内のジョブ数は最初の親キュー可能ジョブを含め最大 5 個です。
- ジョブをチェーニングするとき、実行中のジョブから System.enqueueJob で追加できるジョブは 1 つのみです。つまり、親キュー可能ジョブごとに 1 つの子ジョブしか存在できません。同じキュー可能ジョブからの複数の子ジョブの開始は、サポートされていません。