Apex-batch-processing

提供:Dev Guides
移動先:案内検索

Apex-バッチ処理

この章では、Apexでのバッチ処理について説明します。 おそらく、データのクリーニングや未使用データの削除など、多数のレコードを毎日処理するシナリオを考えてみてください。

Apexの一括処理とは何ですか?

Apexの一括処理はApexコードの非同期実行であり、多数のレコードを処理するために特別に設計されており、同期コードよりもガバナ制限の柔軟性が高くなっています。

Apexの一括処理を使用する場合

  • 毎日または特定の時間間隔で大量のレコードを処理する場合は、Apexの一括処理を使用できます。
  • また、操作を非同期にする場合は、Apexの一括処理を実装できます。 Apexの一括処理は、開発者が実装する必要があるインターフェースとして公開されます。 Apexを使用して、バッチジョブを実行時にプログラムで呼び出すことができます。 バッチApexは、レコードセット全体をカバーし、処理を管理可能なデータチャンクに分割して、レコードの小さなバッチで動作します。

Apexの一括使用

Apexの一括処理を使用する場合、Salesforceが提供するインターフェイスDatabase.Batchableを実装してから、プログラムでクラスを呼び出す必要があります。

次の手順に従うことで、クラスを監視できます-

Apex一括処理ジョブの実行を監視または停止するには、[設定]→[監視]→[Apexジョブ]または[ジョブ]→[Apexジョブ]に移動します。

Apexバッチステップ1の監視

Apex Batch Step2の監視

Database.Batchableインターフェイスには、実装する必要がある次の3つのメソッドがあります-

  • 開始
  • 実行する
  • 終了

ここで、各メソッドを詳細に理解しましょう。

開始

Startメソッドは、Database.Batchableインターフェイスの3つのメソッドの1つです。

構文

global void execute(Database.BatchableContext BC, list<sobject<) {}

このメソッドは、バッチジョブの開始時に呼び出され、バッチジョブが動作するデータを収集します。

メソッドを理解するために、次の点を考慮してください-

  • 単純なクエリを使用してバッチジョブで使用されるオブジェクトのスコープを生成する場合は、 Database.QueryLocator オブジェクトを使用します。 この場合、SOQLデータ行の制限はバイパスされます。
  • レコードを処理する複雑な基準がある場合は、反復可能オブジェクトを使用します。 Database.QueryLocatorは、処理するレコードの範囲を決定します。

実行する

Database.BatchableインターフェースのExecuteメソッドを理解しましょう。

構文

global void execute(Database.BatchableContext BC, list<sobject<) {}

ここで、list <sObject <はDatabase.QueryLocatorメソッドによって返されます。

このメソッドは、Startメソッドの後に呼び出され、バッチジョブに必要なすべての処理を実行します。

終了

Database.BatchableインターフェースのFinishメソッドについて説明します。

  • 構文 *
global void finish(Database.BatchableContext BC) {}

このメソッドは最後に呼び出され、処理されたバッチジョブレコードとステータスに関する情報を電子メールで送信するなど、いくつかの仕上げアクティビティを実行できます。

Apexの一括処理の例

既存の化学会社の例を考えて、アクティブとしてマークされ、今日として日付を作成した顧客レコードの顧客ステータスおよび顧客説明フィールドを更新する必要があると仮定します。 これは毎日行う必要があり、バッチ処理のステータスに関するメールをユーザーに送信する必要があります。 顧客のステータスを「処理済み」に、顧客の説明を「バッチジョブ経由で更新」に更新します。

//Batch Job for Processing the Records
global class CustomerProessingBatch implements Database.Batchable<sobject> {
   global String [] email = new String[] {'[email protected]'};
  //Add here your email address here

  //Start Method
   global Database.Querylocator start (Database.BatchableContext BC) {
      return Database.getQueryLocator('Select id, Name, APEX_Customer_Status__c,
      APEX_Customer_Decscription__c From APEX_Customer__c WHERE createdDate = today
      AND APEX_Active__c = true');
     //Query which will be determine the scope of Records fetching the same
   }

  //Execute method
   global void execute (Database.BatchableContext BC, List<sobject> scope) {
      List<apex_customer__c> customerList = new List<apex_customer__c>();
      List<apex_customer__c> updtaedCustomerList = new List<apex_customer__c>();

     //List to hold updated customer
      for (sObject objScope: scope) {
         APEX_Customer__c newObjScope = (APEX_Customer__c)objScope ;

        //type casting from generic sOject to APEX_Customer__c
         newObjScope.APEX_Customer_Decscription__c = 'Updated Via Batch Job';
         newObjScope.APEX_Customer_Status__c = 'Processed';
         updtaedCustomerList.add(newObjScope);//Add records to the List
         System.debug('Value of UpdatedCustomerList '+updtaedCustomerList);
      }

      if (updtaedCustomerList != null && updtaedCustomerList.size()>0) {
        //Check if List is empty or not
         Database.update(updtaedCustomerList); System.debug('List Size '
          + updtaedCustomerList.size());
        //Update the Records
      }
   }

  //Finish Method
   global void finish(Database.BatchableContext BC) {
      Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

     //Below code will fetch the job Id
      AsyncApexJob a = [Select a.TotalJobItems, a.Status, a.NumberOfErrors,
      a.JobType, a.JobItemsProcessed, a.ExtendedStatus, a.CreatedById,
      a.CompletedDate From AsyncApexJob a WHERE id = :BC.getJobId()];

     //get the job Id
      System.debug('$$$ Jobid is'+BC.getJobId());

     //below code will send an email to User about the status
      mail.setToAddresses(email);
      mail.setReplyTo('[email protected]');//Add here your email address
      mail.setSenderDisplayName('Apex Batch Processing Module');
      mail.setSubject('Batch Processing '+a.Status);
      mail.setPlainTextBody('The Batch Apex job processed'
         + a.TotalJobItems+'batches with '+a.NumberOfErrors+'failures'+'Job Item
      processed are'+a.JobItemsProcessed);
      Messaging.sendEmail(new Messaging.Singleemailmessage [] {mail});
   }
}

このコードを実行するには、まず保存してから、次のコードを匿名実行に貼り付けます。 これにより、クラスのオブジェクトが作成され、Database.executeメソッドがバッチジョブを実行します。 ジョブが完了すると、指定したメールアドレスにメールが送信されます。* アクティブ*がオンになっている顧客レコードがあることを確認してください。

//Paste in Developer Console
CustomerProessingBatch objClass = new CustomerProessingBatch();
Database.executeBatch (objClass);

このクラスが実行されたら、情報が記載されたメールを受信する場所に指定したメールアドレスを確認します。 また、上記の監視ページと手順を使用して、バッチジョブのステータスを確認できます。

デバッグログを確認すると、処理されたレコードの数を示すリストサイズを見つけることができます。

制限事項

一度に処理できるバッチジョブは5つだけです。 これは、Apexの一括処理の制限の1つです。

Apex詳細ページを使用したApexバッチジョブのスケジュール

以下に示すように、Apex詳細ページからApexクラスをスケジュールできます-

  • ステップ1 *-[設定]⇒[Apexクラス]に移動し、[Apexクラス]をクリックします。

詳細ページStep1からApexをスケジュールする

  • ステップ2 *-[Apexのスケジュール]ボタンをクリックします。

詳細ページStep2からApexをスケジュール

  • ステップ3 *-詳細を提供します。

詳細ページStep3からApexをスケジュールする

スケジュール可能なインターフェイスを使用したApexバッチジョブのスケジュール

以下に示すように、スケジュール可能なインターフェイスを使用してApexバッチジョブをスケジュールできます-

//Batch Job for Processing the Records
global class CustomerProessingBatch implements Database.Batchable<sobject> {
   global String [] email = new String[] {'[email protected]'};
  //Add here your email address here

  //Start Method
   global Database.Querylocator start (Database.BatchableContext BC) {
      return Database.getQueryLocator('Select id, Name, APEX_Customer_Status__c,
      APEX_Customer_Decscription__c From APEX_Customer__c WHERE createdDate = today
      AND APEX_Active__c = true');
     //Query which will be determine the scope of Records fetching the same
   }

  //Execute method
   global void execute (Database.BatchableContext BC, List<sobject> scope) {
      List<apex_customer__c> customerList = new List<apex_customer__c>();
      List<apex_customer__c> updtaedCustomerList = new
      List<apex_customer__c>();//List to hold updated customer

      for (sObject objScope: scope) {
         APEX_Customer__c newObjScope = (APEX_Customer__c)objScope ;//type
         casting from generic sOject to APEX_Customer__c
         newObjScope.APEX_Customer_Decscription__c = 'Updated Via Batch Job';
         newObjScope.APEX_Customer_Status__c = 'Processed';
         updtaedCustomerList.add(newObjScope);//Add records to the List
         System.debug('Value of UpdatedCustomerList '+updtaedCustomerList);
      }

      if (updtaedCustomerList != null && updtaedCustomerList.size()>0) {
        //Check if List is empty or not
         Database.update(updtaedCustomerList); System.debug('List Size'
            + updtaedCustomerList.size());
        //Update the Records
      }
   }

  //Finish Method
   global void finish(Database.BatchableContext BC) {
      Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

     //Below code will fetch the job Id
      AsyncApexJob a = [Select a.TotalJobItems, a.Status, a.NumberOfErrors,
      a.JobType, a.JobItemsProcessed, a.ExtendedStatus, a.CreatedById,
      a.CompletedDate From AsyncApexJob a WHERE id = :BC.getJobId()];//get the job Id
      System.debug('$$$ Jobid is'+BC.getJobId());

     //below code will send an email to User about the status
      mail.setToAddresses(email);
      mail.setReplyTo('[email protected]');//Add here your email address
      mail.setSenderDisplayName('Apex Batch Processing Module');
      mail.setSubject('Batch Processing '+a.Status);
      mail.setPlainTextBody('The Batch Apex job processed'
         + a.TotalJobItems+'batches with '+a.NumberOfErrors+'failures'+'Job Item
      processed are'+a.JobItemsProcessed);
      Messaging.sendEmail(new Messaging.Singleemailmessage [] {mail});
   }

  //Scheduler Method to scedule the class
   global void execute(SchedulableContext sc) {
      CustomerProessingBatch conInstance = new CustomerProessingBatch();
      database.executebatch(conInstance,100);
   }
}

//Paste in Developer Console
CustomerProessingBatch objClass = new CustomerProcessingBatch();
Database.executeBatch (objClass);