この文章は Salesforce 機械翻訳システムを使用して翻訳されました。詳細はこちらをご参照ください。
英語に切り替える

キュー可能 Apex

非同期 Apex プロセスを制御するには、Queueable インターフェースを使用します。このインターフェースを使用すると、ジョブをキューに追加して監視できます。これにより、future メソッドを使用する場合に比べ、非同期 Apex コードの実行が機能強化されます。

大規模なデータベース操作や外部 Web サービスのコールアウトなど、実行に長時間かかる Apex プロセスの場合、Queueable インターフェースを実装し、ジョブを Apex ジョブキューに追加することでそれらのプロセスを非同期に実行できます。この場合、非同期 Apex ジョブは、それ自身のスレッドのバックグラウンドで実行され、メインの Apex ロジックの実行を遅延させることはありません。キュー内にある各ジョブは、システムリソースが使用可能になると実行されます。Queueable インターフェースメソッドを使用するメリットは、ヒープサイズ制限など一部のガバナ制��値が、同期 Apex の場合よりも緩和される点にあります。

キュー可能ジョブと future メソッドはどちらもキューに入れられてから実行されるという点で似ていますが、キュー可能ジョブには次のようなメリットもあります。
  • ジョブ ID の取得: System.enqueueJob メソッドを呼び出してジョブを送信すると、メソッドは新しいジョブの ID を返します。この ID は AsyncApexJob レコードの ID に対応します。この ID を使用し、Salesforce ユーザインターフェースの Apex ジョブページから、またはプログラムで AsyncApexJob のレコードをクエリすることで、ジョブを識別してその進行状況を監視できます。
  • 非プリミティブ型の使用: キュー可能クラスには、sObject 型やカスタム Apex 型など、非プリミティブデータ型のメンバー変数を含めることができます。これらのオブジェクトには、ジョブの実行時にアクセスできます。
  • ジョブのチェーニング: 実行中のジョブから 2 つ目のジョブを開始することで、2 つのジョブを連鎖的に実行することができます。ジョブのチェーニングは、別の先行プロセスに依存する処理を実行する必要がある場合に便利です。

これは、Queueable インターフェースの実装例です。この例の execute メソッドは、新規取引先を挿入します。
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 です。

キュー可能ジョブのテスト

次の例では、テストメソッドでキュー可能ジョブの実行する方法を示します。キュー可能ジョブは、非同期プロセスです。このプロセスがテストメソッド内で実行されるようにするには、ジョブを Test.startTestTest.stopTest 間のブロック内でキューに送信する必要があります。システムは、テストメソッドで開始されたすべての非同期プロセスを、Test.stopTest ステートメントの後に同期して実行します。次に、テストメソッドは、ジョブで作成された取引先をクエリして、キュー可能ジョブの結果を検証します。
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}

キュー可能 Apex ジョブの ID はテストコンテキスト内では返されません。実行テストで System.enqueueJobnull を返します。

メモ

ジョブのチェーニング

最初に別のジョブで他の処理を実行した後にジョブを実行する必要がある場合、キュー可能ジョブをチェーニングできます。ジョブを別のジョブにチェーニングするには、キュー可能クラスの 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 ジョブです。
  • チェーニングされたジョブの深度に制限はありません。つまり、1 つのジョブから別のジョブにチェーニングし、このプロセスを新しい子ジョブごとに繰り返して新しい子ジョブにリンクできます。Developer Edition 組織およびトライアル組織の場合、チェーニングされたジョブの最大スタック深度は 5 です。つまり、ジョブのチェーニングを 4 回行うことができ、チェーン内のジョブ数は最初の親キュー可能ジョブを含め最大 5 個です。
  • ジョブをチェーニングするとき、実行中のジョブから System.enqueueJob で追加できるジョブは 1 つのみです。つまり、親キュー可能ジョブごとに 1 つの子ジョブしか存在できません。同じキュー可能ジョブからの複数の子ジョブの開始は、サポートされていません。