【Salesforce】Apexバッチとは?(サンプルコード、スケジュール方法)

Salesforce

こんにちは、ヨリユです。
本記事ではApexバッチについてサンプルコードを例に解説していきます。
また、Apexバッチのスケジュール方法についても解説していきます。

【この記事から学べること】
・Apexバッチ実装に必要なメソッドと特徴
・Apexバッチの実装例
・Apexバッチのスケジュール方法(UI、コード)

Apexバッチとは?

SalesforceのApexバッチは、大量のレコードを一括処理する際に使用されます。
同期処理で数百〜数千万のレコードを更新しようとするとガバナ制限に抵触することがあります。
Apexバッチは非同期に実行され、トランザクションごとに新しいガバナ制限が適用されるため、ガバナ制限を回避して大量のレコードを処理することができます。
大量のレコードをアーカイブ、データクレンジングする場合には、Apexバッチが適しているといえるでしょう。

Apexバッチの実装

Apexバッチを実装するには、Salesforceが提供するインターフェースの一つであるDatabase.Batchableを実装します。
次の3つのメソッドを実装します。

  • startメソッド
  • executeメソッド
  • finishメソッド

startメソッド

start メソッドは、Apexバッチで最初に呼び出されるメソッドです。

バッチ処理するレコードを取得し、executeメソッドに渡します。
executeメソッドに渡すオブジェクトは、Database.QueryLocator、またはIterableになります。通常はDatabase.QueryLocatorを使用しますが、外部連携や複雑なオブジェクト構造を扱いたいときにはIterableオブジェクトを使用します。

QueryLocatorを使用する場合、SOQLで最大5000万件のレコードを取得できます。
一方、Iterableを使用する場合は、SOQLで取得できるレコード総数のガバナ制限(最大 5万件)は引き続き適用されます。

executeメソッド

executeメソッドは、バッチ(データの処理単位)ごとに処理を実行するメソッドです。

処理するレコードは、startメソッドからバッチサイズに分割されて渡されます。
バッチサイズは省略可能で、デフォルトサイズは200です。

例えば、バッチサイズが200、startメソッドで2,000件のレコードを取得した場合、10個のトランザクションに分割され、executeメソッドが実行されます。ガバナ制限は、各トランザクション単位で適用されます。

finishメソッド

finishメソッドは、Apexバッチで最後に呼び出されるメソッドです。

すべてのバッチが処理された後、1回呼び出されます。
バッチ処理が終了したことを通知する確認メール送信など、後処理を行います。

Apexバッチのサンプルコード

以下、Apexバッチのサンプルコードです。
大まかな流れは、「データ取得(start)」→「データ処理(execute)」→「後処理(finish)」となります。
startメソッドは、条件に一致する取引先を取得しています。
executeメソッドは、startメソッドで取得した取引先の項目「説明」の値を更新しています。
finishメソッドは、サンプルコードのため、処理を実装していません。

public class MyBatch implements Database.Batchable <sobject> {
    
    public Database.QueryLocator start(Database.BatchableContext bc){
        System.debug('*** start ***');
        String query = 'Select Id, Name, Description From Account Where Name Like \'Apexバッチテスト%\'';
        return Database.getQueryLocator(query);          
    }
    
    public void execute(Database.BatchableContext bc, List<Account> scope){
        System.debug('*** execute ***');
        List<Account> updList = new List<Account>();
        for(Account acc : scope){
            Account newAcc = new Account();
            newAcc.Id = acc.Id;
            newAcc.Description = 'Apexバッチによって更新。';
            updList.add(newAcc);
        }        
        if(updList.size() > 0){
            update updList;  
        }     
    }
    
    public void finish(Database.BatchableContext bc){
        System.debug('*** finish ***');
    }
}

Apexバッチのスケジュール

Apexバッチは、スケジュールを設定し、定期的に実行できます。

スケジュール設定方法は以下の2つ。

  • UIで設定
  • コードで設定

Apexバッチスケジュールのサンプルコード

以下、Apexバッチスケジュールのサンプルコードです。
バッチサイズ200でApexバッチクラス「MyBatch」を呼び出すシンプルなものです。

public with sharing class MyBatchSchedule implements Schedulable {
    private final Integer BATCH_SIZE = 200;
    public void execute(SchedulableContext bc) {
        MyBatch b = new MyBatch();
        Database.executeBatch(b, BATCH_SIZE);
    }
}

UIで設定

以下、ApexバッチのスケジュールをUIで設定していきます。

  1. 「設定 > ホーム > Apex クラス」 で「Apexをスケジュール」をクリック。
Apexバッチスケジュール UIで設定1
  1. 項目を入力し、「保存」をクリック。

【入力項目】
①ジョブ名:ジョブ名を入力。処理の要約など。
②Apexクラス:Schedulableインターフェイスが実装されたApexクラスを指定可能
③Apexの実行をスケジュール:頻度、開始日、終了日、希望開始時刻(※)を入力。
(※)希望開始時刻は分単位で指定できない。1時間ごとのみ指定可能。
   例えば9:30など、分単位で指定したい場合は、コードで設定する必要がある。

  1. 「設定 > ホーム > スケジュール済みジョブ」 でスケジュールしたジョブを確認。

コードで設定

以下、Apexバッチのスケジュールをコードで設定していきます。

  1. 「設定」から「開発者コンソール」をクリック。
salesforce-apex-batch-4
  1. 開発者コンソール画面で「Debug > Open Execute Anonymous Window」をクリックし、「Enter Apex Code」画面を表示。(ショートカット:CTRL + E)
salesforce-apex-batch-5
  1. 以下のコードを入力し、「execute」をクリック。
System.schedule('テストジョブ(コードで設定)', '0 30 9 * * ?', new MyBatchSchedule());

第一引数:ジョブ名。
第二引数:スケジュール日時。左から「秒、分、時、日、月、曜日、年」 ※年のみ省略化
第三引数:Apexスケジュールクラス。

salesforce-apex-batch-6
  1. 「設定 > ホーム > スケジュール済みジョブ」 でスケジュールしたジョブを確認。
    ※コードでスケジュールした場合、アクション「Manage」は表示されません。
salesforce-apex-batch-7

おわりに

いかがでしたでしょうか。
Apexバッチは大量レコードを処理したり、非同期に処理を実行できるので、よく使われると思います。
ぜひ実際に手を動かしながら、使い方を身につけていきましょう!
最後までご覧いただきありがとうございました!