Newer Version Available
Apex の一括処理の使用
Apex の一括処理を使用するには、Salesforce が提供するインターフェース Database.Batchable を実装する Apex クラスを記述し、次にプログラムでクラスを呼び出す必要があります。
Apex の一括処理ジョブの実行を監視または停止するには、[設定] から または をクリックします。
Database.Batchable インターフェースの実装
-
start メソッド
start メソッドは、Apex の一括処理ジョブの開始時にコールされます。start メソッドは、インターフェースメソッド execute に渡すレコードまたはオブジェクトを収集するために使用します。このメソッドは、Database.QueryLocator オブジェクト、またはジョブに渡すレコードやオブジェクトを含む Iterable オブジェクトを返します。
Database.QueryLocator オブジェクトは、一括処理ジョブで使用するオブジェクトの範囲を単純なクエリ (SELECT) で作成する場合に使用します。QueryLocator オブジェクトを使用する場合、SOQL クエリによって取得されるレコード合計数に対するガバナ制限は無視されます。たとえば、Account オブジェクトに対する Apex の一括処理ジョブでは、組織内のすべての取引先レコード (最大 5000 万件のレコード) の QueryLocator を返すことができます。��た、Contact オブジェクトに対して共有再適用を行うと、組織内のすべての取引先レコードの QueryLocator が返されます。
Iterable オブジェクトは、一括処理ジョブに複雑な範囲を作成する必要がある場合に使用します。また、リスト全体を反復する独自のカスタムプロセスを作成するために Iterable オブジェクトを使用することもできます。 -
execute メソッド
execute メソッドは、メソッドに渡す一括レコードごとにコールされます。データの処理単位ごとに必要な処理をすべて実行する場合に、このメソッドを使用します。
このメソッドは次を取得します。- Database.BatchableContext オブジェクトへの参照。
- List<sObject> などの sObjects のリストまたはパラメータ化された型のリスト。Database.QueryLocator を使用している場合は、返されたリストが使用されます。
レコードの一括処理は、start メソッドから受け取る順序で実行されます。
-
finish メソッド
finish メソッドは、すべての一括処理が行われた後にコールされます。確認メールの送信や後処理操作を行う場合に、このメソッドを使用します。
Apex の一括処理ジョブの各実行は、個別のトランザクションとみなされます。たとえば、1,000 件のレコードを含む Apex の一括処理ジョブが、Database.executeBatch から任意の scope パラメータを指定せずに実行されると、このジョブはそれぞれ 200 件のレコードを含む 5 つのトランザクションとみなされます。Apex のガバナ制限は、各トランザクションでリセットされます。最初のトランザクションが成功し、2 番目が失敗した場合、最初のトランザクションで行われたデータベースの更新はロールバックされません。
Database.BatchableContext の使用
Database.Batchable インターフェースのすべてのメソッドは Database.BatchableContext オブジェクトへの参照を必要とします。このオブジェクトは、一括処理ジョブの進行状況を追跡するために使用します。
| 名前 | 引数 | 戻り値 | 説明 |
|---|---|---|---|
| getJobID | ID | この一括処理ジョブに関連付けられている AsyncApexJob オブジェクトの ID を文字列として返します。このメソッドは、一括処理ジョブのレコードの進行状況を追跡するために使用します。System.abortJob メソッドでもこの ID を使用できます。 |
次の例では、Database.BatchableContext を使用して、一括処理ジョブに関連付けられている AsyncApexJob をクエリします。
Database.QueryLocator を使用した範囲の定義
start メソッドは、一括処理ジョブで使用するレコードを含む Database.QueryLocator オブジェクトまたは Iterable オブジェクトを返します。
Apex の一括処理に Iterable オブジェクトを使用した範囲の定義
start メソッドは、一括処理ジョブで使用するレコードを含む Database.QueryLocator オブジェクトまたは Iterable オブジェクトを返します。Iterable オブジェクトを使用すると、より簡単に項目を返すことができます。
Database.executeBatch メソッドを使用した一括処理ジョブの送信
- Database.Batchable インターフェースを実装するクラスのインスタンス。
- 省略可能なパラメータ scope。このパラメータは、execute メソッドに渡すレコードの数を指定します。このパラメータは、メソッドに渡す各レコードに対して多数の処理があり、ガバナ制限に達する場合に使用します。レコード数を制限することによって、トランザクションあたりの処理が制限されます。この値は 0 より大きくする必要があります。一括処理クラスの start メソッドが QueryLocator を返す場合、Database.executeBatch の省略可能な範囲パラメータには最大値 2,000 を指定できます。これより大きい値に設定すると、Salesforce では、QueryLocator が返すレコードを、最大 2,000 レコードまでの、より小さいバッチに分割します。一括処理クラスの start メソッドが Iterable オブジェクトを返す場合、scope パラメータ値に上限はありませんが、非常に大きい値を使用すると、他の制限が発生する場合があります。
System.abortJob メソッドでもこの ID を使用できます。
AsyncApexJob オブジェクトについての詳細は、『Salesforce および Force.com のオブジェクトリファレンス』の「AsyncApexJob」を参照してください。
Apex Flex キュー内での一括処理ジョブの保留
Apex Flex キューでは、100 件まではエラーにならずに一括処理ジョブを送信できます。
- 一括処理ジョブは Apex Flex キューに置かれ、その状況は Holding に設定されます。
- Apex Flex キューが最大ジョブ数の 100 に達した場合、Database.executeBatch は LimitException を発生させて、ジョブをキューに追加しません。
Apex Flex キュー内のジョブの並び替え
送信したジョブの状況が Holding である間は、Salesforce ユーザインターフェースでジョブを並び替えてどの一括処理ジョブが最初に処理されるかを制御できます。この操作を行うには、[設定] から、 をクリックします。
システム管理者は、Apex Flex キューに保留されているジョブの順序を変更して、いつシステムに処理されるかを制御できます。たとえば、システム管理者は一括処理ジョブを保留キューの先頭位置まで移動して、システムが Flex キューから次の保留ジョブを取得するときに最初に処理されるようにすることができます。ジョブは、システム管理者の介入なしに、送信された順序 (先入れ先出し) で処理されます。システムリソースが使用可能になったら、システムが Apex Flex キューの先頭から次のジョブを取り出し、一括処理ジョブキューに移動します。組織ごとに、システムでは最大 5 件のキュー内のジョブまたは有効なジョブを同時に処理できます。移動したこれらのジョブの状況は、Holding から Queued に変わります。キュー内にあるジョブは、システムが新しいジョブを処理できる状態になると実行されます。[Apex ジョブ] ページで、キューに入れたジョブを監視できます。
一括処理ジョブの状況
次の表に、一括処理ジョブで発生するすべての状況と、それぞれの説明を示します。
| 状況 | 説明 |
|---|---|
| 保留 | ジョブは送信済みで、システムリソースが使用可能になって処理用のキューにジョブを追加できるようになるまで Apex Flex キュー内に保持されています。 |
| キュー | ジョブは実行待ちです。 |
| 準備中 | ジョブの start メソッドが呼び出されました。この状況は、レコードのバッチサイズに応じて数分かかることがあります。 |
| 処理中 | ジョブは処理中です。 |
| 中止 | ジョブはユーザによって中止されました。 |
| 完了 | ジョブはエラーあり/なしで完了しました。 |
| 失敗 | ジョブでシステム障害が発生しました。 |
System.scheduleBatch メソッドの使用
System.scheduleBatch メソッドを使用して、一括処理ジョブを将来のある時点で一度実行するようにスケジュールできます。
- Database.Batchable インターフェースを実装するクラスのインスタンス。
- ジョブ名。
- ジョブを実行開始するまでの分単位の期間。
- 範囲の値 (省略可能)。このパラメータは、execute メソッドに渡すレコードの数を指定します。このパラメータは、メソッドに渡す各レコードに対して多数の処理があり、ガバナ制限に達する場合に使用します。レコード数を制限することによって、トランザクションあたりの処理が制限されます。この値は 0 より大きくする必要があります。start メソッドが QueryLocator を返す場合、System.scheduleBatch の省略可能な範囲パラメータには最大値 2,000 を指定できます。これより大きい値に設定すると、Salesforce では、QueryLocator が返すレコードを、最大 2,000 レコードまでの、より小さいバッチに分割します。start メソッドが Iterable オブジェクトを返す場合、scope パラメータ値に上限はありませんが、非常に大きい値を使用すると、他の制限が発生する場合があります。
System.scheduleBatch メソッドは、スケジュール済みジョブ ID (CronTrigger ID) を返します。
CronTrigger についての詳細は、『Salesforce および Force.com のオブジェクトリファレンス』の「CronTrigger」を参照してください。
Apex の一括処理の例
Apex の一括処理での状態の使用
Apex の一括処理ジョブの各実行は、個別のトランザクションとみなされます。たとえば、1,000 件のレコードを含む Apex の一括処理ジョブが、任意の scope パラメータを指定せずに実行されると、このジョブはそれぞれ 200 件のレコードを含む 5 つのトランザクションとみなされます。
クラス定義で Database.Stateful を指定すると、これらのトランザクション間で状態を保持できます。Database.Stateful を使用するとき、インスタンスメンバー変数のみがトランザクション間で値を保持します。静的メンバー変数は、トランザクション間で値を保持せず、リセットされます。状態を保持すると、処理されているレコードをカウントまたは集計する場合に役立ちます。たとえば、ジョブで商談レコードが処理されたとします。execute でメソッドを定義し、処理された商談数の合計を集計できます。
Database.Stateful を指定しない場合、すべての静的メンバー変数とインスタンスメンバー変数が元の値に戻されます。
initialState はクラスの「最初の」状態です。これを使用して、一括処理ジョブの実行時にクラスのインスタンス間で情報を受け渡すことはできません。たとえば、execute で initialState の値を変更した場合、2 番目に処理されたレコード群は、新しい値にアクセスできません。最初の値のみにアクセスできます。
Apex の一括処理のテスト
Apex の一括処理をテストするとき、execute メソッドの 1 つの実行だけをテストできます。executeBatch メソッドの scope パラメータを使用して、execute メソッドに渡されるレコード数を制限し、ガバナ制限に達しないようにすることができます。
executeBatch メソッドは、匿名プロセスを開始します。これは、Apex の一括処理をテストする場合、結果に対してテストする前に一括処理ジョブを終了する必要があることを意味します。executeBatch メソッドを実行する前後で、テストメソッド startTest と stopTest を使用して、テストを続行する前に一括処理ジョブが終了するようにします。startTest メソッドの後に作成されたすべての非同期コールはシステムによって収集されます。stopTest を実行する場合、すべての非同期プロセスが同期して実行されます。startTest メソッドおよび stopTest メソッド内に executeBatch メソッドを含めない場合、一括処理ジョブは Salesforce API バージョン 25.0 以降を使用して保存された Apex のテストメソッドでは最後に実行されますが、それよりも前のバージョンで保存された Apex の場合は実行されません。
Apex の一括処理のガバナ制限
- 最大 5 件の一括処理ジョブを同時にキューに追加するか、有効にできます。
- 最大 100 個の一括処理ジョブを Apex Flex キュー内で保留できます。
- 実行中のテストでは、最大 5 件の一括処理ジョブを送信できます。
- 24 時間での Apex 一括処理メソッドの最大実行数は、250,000 または組織のライセンス数の 200 倍のいずれか大きいほうです。メソッドの実行数には、start、execute、および finish メソッドの実行が含まれます。これは組織全体の制限で、他のすべての非同期 Apex (Apex 一括処理、キュー可能 Apex、スケジュール済み Apex、および future メソッド) と共有されます。この制限のカウント対象となるライセンスは、Salesforce フルユーザライセンスまたは Force.com アプリケーションサブスクリプションのユーザライセンスです。Chatter Free、Chatter カスタマーユーザ、カスタマーポータルユーザ、およびパートナーポータルユーザライセンスは含まれません。
- Apex 一括処理の start メソッドは、ユーザごとに同時に最大 15 個のクエリカーソルを開くことができます。Apex 一括処理の execute および finish メソッドにはそれぞれ、ユーザごとに開けるクエリカーソルは 5 個までという制限があります。
- Database.QueryLocator オブジェクトでは最大 5,000 万件のレコードが返されます。5,000 万件以上のレコードが返された場合、一括処理ジョブは即座に終了し「失敗」とマークされます。
- 一括処理クラスの start メソッドが QueryLocator を返す場合、Database.executeBatch の省略可能な範囲パラメータには最大値 2,000 を指定できます。これより大きい値に設定すると、Salesforce では、QueryLocator が返すレコードを、最大 2,000 レコードまでの、より小さいバッチに分割します。一括処理クラスの start メソッドが Iterable オブジェクトを返す場合、scope パラメータ値に上限はありませんが、非常に大きい値を使用すると、他の制限が発生する場合があります。
- Database.executeBatch の scope パラメータ (省略可能) でサイズが指定されない場合、Salesforce では start メソッドによって返されるレコードを 200 個ずつのバッチに分割し、各バッチを execute メソッドに渡します。Apex ガバナ制限は、execute の各実行でリセットされます。
- start、execute、および finish メソッドは、それぞれ最大 10 回のコールアウトを実装できます。
- Apex の一括処理ジョブの start メソッドは、組織内で一度に 1 つのみ実行できます。キュー内のまだ開始されていない一括処理ジョブは、開始されるまで保持されます。なお、この制限により一括処理ジョブが失敗することはありません。また、複数のジョブが実行されている場合は、Apex の一括処理ジョブの execute メソッドが並行して実行されます。
Apex の一括処理のベストプラクティス
- 一括処理ジョブをトリガから開始する場合は、細心の注意を払ってください。トリガで一括処理ジョブが制限を超えて追加されないようにする必要があります。特に、API の一括更新、インポートウィザード、ユーザインターフェースを使用したレコードの一括変更、および複数のレコードを一度に更新するすべての処理については十分に考慮してください。
- Database.executeBatch をコールしたときに Salesforce が行うのは、そのジョブをキューに入れることのみです。実際の実行は、サービスの使用可能状態に応じて遅れる場合があります。
- Apex の一括処理をテストするとき、execute メソッドの 1 つの実行だけをテストできます。executeBatch メソッドの scope パラメータを使用して、execute メソッドに渡されるレコード数を制限し、ガバナ制限に達しないようにすることができます。
- executeBatch メソッドは、匿名プロセスを開始します。これは、Apex の一括処理をテストする場合、結果に対してテストする前に一括処理ジョブを終了する必要があることを意味します。executeBatch メソッドを実行する前後で、テストメソッド startTest と stopTest を使用して、テストを続行する前に一括処理ジョブが終了するようにします。
- ジョブトランザクション全体でインスタンスメンバー変数またはデータを共有する場合は、クラス定義で Database.Stateful を使用します。これを使用しない場合、各トランザクションの開始時にすべてのメンバー変数が初期状態にリセットされます。
- future として宣言されたメソッドは、Database.Batchable インターフェースを実装するクラスでは使用できません。
- future として宣言されたメソッドは、Apex の一括処理クラスからはコールできません。
- 一括処理ジョブでは、getContent および getContentAsPDF PageReference メソッドは使用できません。
- Apex の一括処理ジョブが実行されると、一括処理ジョブを送信したユーザにメール通知が送信されます。または、管理パッケージにコードが含まれ、登録組織が一括処理ジョブを実行している場合、[Apex の例外の通知受信者] 項目に表示された受信者にメールが送信されます。
- 各メソッドの実行では、標準のガバナ制限が、匿名ブロック、Visualforce コントローラ、または WSDL メソッド同様に適用されます。
- Apex の一括処理が呼び出されるたびに AsyncApexJob レコードが作成されます。このレコードの ID を使用して、ジョブの状況、エラーの数、進行状況、申請者を取得する SOQL クエリを構成します。AsyncApexJob オブジェクトについての詳細は、『Salesforce および Force.com のオブジェクトリファレンス』の「AsyncApexJob」を参照してください。
- 10,000 件ごとの AsyncApexJob レコードに対して、Apex では、内部で使用するための BatchApexWorker タイプの追加の AsyncApexJob レコードを作成します。すべての AsyncApexJob レコードをクエリする場合は、JobType 項目を使用して BatchApexWorker タイプのレコードを除外することを���勧めします。除外しない場合、クエリにより 10,000 件の AsyncApexJob レコードごとに複数のレコードが返されます。AsyncApexJob オブジェクトについての詳細は、『Salesforce および Force.com のオブジェクトリファレンス』の「AsyncApexJob」を参照してください。
- クラス内のすべてのメソッドは global または public として定義する必要があります。
- 共有再適用の場合、一括処理内のレコードに対する Apex による共有管理を、すべて execute メソッドで削除してから再作成することをお勧めします。そうすることで、正確で完全な共有が適用されます。
- Salesforce サービスメンテナンスダウンタイム前にキューに入れられた一括処理ジョブは、キューに入れられたままになります。サービスのダウンタイムが終了してシステムリソースが使用可能になったときに、キューにある一括処理ジョブが実行されます。ダウンタイム発生時に一括処理ジョブが実行されていた場合、その一括処理の実行はロールバックされ、サービスが再開された後に再度開始されます。
- 可能ならば、一括処理の数は最小限に抑えてください。Salesforce では、キューベースのフレームワークを使用して、future メソッドや Apex 一括処理などのソースからの非同期プロセスを処理します。このキューは、組織間で要求ワークロードを調整するために使用します。キュー内で 1 つの組織の未処理要求が 2,000 を上回ると、その組織からの以降の要求は遅延し、その間に他の組織からの要求が処理されます。
- 一括処理ジョブができるだけ高速に実行されるようにします。一括処理ジョブを高速に実行するには、Web サービスコールアウト回数を最小限にし、Apex の一括処理コードで使用されるクエリを調整します。キュー内のジョブ数が多い場合、一括処理ジョブの実行時間が長くなるほど、キューにある他のジョブが遅延する可能性が高くなります。
一括処理ジョブのチェーニング
API バージョン 26.0 以降、既存の一括処理ジョブから別の一括処理ジョブを開始するように、ジョブをチェーニングできます。一括処理ジョブをチェーニングすることで、大量のデータを処理する場合など、ジョブでバッチでの処理が必要な場合に、別のジョブが終了するとジョブが開始します。または、一括処理が必要ではない場合は、Queueable Apex の使用を検討してください。
一括処理ジョブをチェーニングするには、現在の一括処理クラスの finish メソッドから Database.executeBatch または System.scheduleBatch をコールします。新しい一括処理ジョブは、現在の一括処理ジョブが終了すると開始します。
以前の API バージョンでは、Apex の一括処理メソッドから Database.executeBatch と System.scheduleBatch はコールできませんでした。使用されるバージョンは、他の一括処理ジョブを開始またはスケジュールする、実行中の一括処理クラスのバージョンです。実行中の一括処理クラスの finish メソッドで、一括処理ジョブを開始するヘルパークラスのメソッドをコールする場合は、ヘルパークラスの API バージョンは関係ありません。