future のメソッド
future メソッドは、バッググラウンドで非同期で実行されます。外部 Web サービスへのコールアウト、独自のスレッドを独自の時間に実行する処理など、長時間にわたる処理を実行する場合に future メソッドをコールできます。また、混合 DML エラーを回避するために異なる sObject 型に対する DML 操作を分離する場合にも future メソッドを使用できます。各 future メソッドは、キューに入れられ、システムリソースが使用可能になったときに実行されます。この方法によって、長時間にわたる処理の完了を待たずにコードを実行できます。future メソッドを使用する利点は、SOQL クエリの制限やヒープサイズ制限など、一部のガバナ制限値が高くなる点にあります。
future メソッドを定義するには、単に次のように future アノテーションを使用してアノテーションを付加します。
future アノテーションのあるメソッドは静的メソッドである必要があり、void 型のみを返します。指定するパラメータはプリミティブデータ型、プリミティブデータ型の配列、プリミティブデータ型のコレクションである必要があります。future アノテーションのあるメソッドは、sObject またはオブジェクトを引数として取ることはできません。
future メソッドに sObject を引数として渡せない理由は、メソッドをコールしてからそのメソッドを実行するまでの間に sObject が変更されてしまう可能性があるためです。この場合、future メソッドが以前の sObject 値を取得して新しい値を上書きしてしまう可能性があります。データベースにすでに存在する sObject を使用するには、代わりに sObject ID (または ID のコレクション) を渡し、ID を使用して最新のレコードに対してクエリを実行します。次の例では、ID のリストを使用してこれを実行する方法を示します。
次の例は、外部サービスへのコールアウトを実行する future メソッドの骨格です。このアノテーションは、コールアウトが許可されることを示す追加パラメータ (callout=true) を取っています。コールアウトについての詳細は、「Apex を使用したコールアウトの呼び出し」を参照してください。
null 以外のロールを持つユーザの挿入は、他の sObject に対する DML 操作とは別のスレッドで実行する必要があります。次の例では、future メソッドを使用してこれを行っています。future メソッド insertUserWithRole は、Util クラスで定義され、COO ロールを持つユーザの挿入を実行します。この future メソッドを使用するには、組織に COO ロールを定義しておく必要があります。MixedDMLFuture の useFutureMethod メソッドで、取引先が挿入され、future メソッド insertUserWithRole がコールされます。
次は、null 以外のロールを持つユーザを挿入する future メソッドが含まれる、Util クラスの定義です。
これは、上記で定義した future メソッドをコールするメインメソッドが含まれるクラスです。
future メソッドを呼び出す方法は、他のメソッドを呼び出す方法と同じです。ただし、future メソッドで別の future メソッドを呼び出すことはできません。
future アノテーションのあるメソッドには次のような制限事項があります。
- Apex 呼び出しごとの、メソッドのコール数は batch および future のコンテキストの場合 0 以下、queueable コンテキストの場合 1
- 24 時間あたりの future メソッドの最大呼び出し数は、250,000 または組織のユーザライセンス数の 200 倍のいずれか大きい方です。これは組織全体の制限で、他のすべての非同期 Apex (Apex 一括処理、キュー可能 Apex、スケジュール済み Apex、および future メソッド) と共有されます。使用可能な非同期 Apex 実行の数を確認するには、REST API limits リソースに対して要求を実行します。『REST API 開発者ガイド』の「組織の制限をリストする」を参照してください。この制限に反映されるライセンスの種類は、Salesforce フルユーザライセンス、Salesforce Platform ユーザライセンス、アプリケーションサブスクリプションのユーザライセンス、Chatter Only ユーザ、Identity ユーザ、Company Community ユーザです。
future メソッドのテスト
future アノテーションのあるメソッドをテストするには、startTest() と stopTest() の間のコードブロックでメソッドを含むクラスをコールします。startTest メソッドの後に実行されたすべての非同期コールはシステムによって収集されます。stopTest を実行する場合、すべての非同期プロセスが同期して実行されます。
future メソッドのパフォーマンスのベストプラクティス
Salesforce では、キューベースのフレームワークを使用して、future メソッドや Apex の一括処理などの提供元からの非同期プロセスを処理します。このキューは、組織間で要求ワークロードを調整するために使用します。組織が非同期プロセスでキューを効率的に使用していることを確認するには、次のベストプラクティスを使用します。
- 可能な限り、非同期キューに多数の future メソッドを追加することは避けます。キュー内で 1 つの組織の未処理要求が 2,000 を上回ると、その組織からの以降の要求は遅延し、その間に他の組織からの要求が処理されます。
- future メソッドができるだけ速く実行されるようにします。一括処理ジョブの高速実行を実現するには、Web サービスのコールアウト時間を最小化し、future メソッドで使用されるクエリを調整します。キュー内に多数の要求がある場合、future メソッドの実行時間が長くなるにつれ、キューにある他の要求が遅延する可能性が高くなります。
- future メソッドをより大規模にテストします。可能な場合は、予想される最大数の future メソッドを生成する環境を使用してテストします。これは遅延が発生するかどうかの判断に役立ちます。
- 多数のレコードの処理には、future メソッドの代わりに Apex 一括処理の使用を検討します。