当前位置: 首页 > 文档资料 > Apex 中文教程 >

批处理( Batch Processing)

优质
小牛编辑
132浏览
2023-12-01

在本章中,我们将了解Apex中的批处理。 考虑一种情况,我们将每天处理大量记录,可能是清理数据或删除一些未使用的数据。

什么是Batch Apex?

Batch Apex是Apex代码的异步执行,专门用于处理大量记录,并且在调控器限制方面比同步代码具有更大的灵活性。

何时使用Batch Apex?

  • 如果您希望每天或甚至在特定的间隔时间内处理大量记录,那么您可以选择Batch Apex。

  • 此外,当您希望操作异步时,您可以实现Batch Apex。 Batch Apex作为必须由开发人员实现的接口公开。 可以使用Apex在运行时以编程方式调用批处理作业。 Batch Apex在小批量记录上运行,覆盖整个记录集并将处理分解为可管理的数据块。

使用Batch Apex

当我们使用Batch Apex时,我们必须实现Salesforce提供的接口Database.Batchable,然后以编程方式调用该类。

您可以按照以下步骤监控class -

要监视或停止批处理Apex批处理作业的执行,请转至设置→监控→Apex作业或作业→Apex作业。

监控Apex Batch Step1

监控Apex Batch Step2

Database.Batchable接口有以下三种需要实现的方法 -

  • Start
  • Execute
  • Finish

现在让我们详细了解每种方法。

Start

Start方法是Database.Batchable接口的三种方法之一。

Syntax

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

将在批处理作业启动时调用此方法,并收集批处理作业将在其上运行的数据。

请考虑以下几点来理解该方法 -

  • 使用简单查询生成批处理作业中使用的对象范围时,请使用Database.QueryLocator对象。 在这种情况下,将绕过SOQL数据行限制。

  • 如果您有复杂的条件来处理记录,请使用iterable对象。 Database.QueryLocator确定应处理的记录范围。

Execute

现在让我们了解Database.Batchable接口的Execute方法。

Syntax

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

其中,list

此方法在Start方法之后调用,并执行Batch Job所需的所有处理。

Finish

我们现在将讨论Database.Batchable接口的Finish方法。

Syntax

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[] {'test@test.com'};
   // 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('test@test.com'); // 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});
   }
}

要执行此代码,请先保存它,然后将以下代码粘贴到Execute anonymous中。 这将创建类的对象,Database.execute方法将执行Batch作业。 作业完成后,电子邮件将发送到指定的电子邮件地址。 确保您的客户记录已选中“已Active ”。

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

执行此课程后,请检查您提供的电子邮件地址,以便您收到包含信息的电子邮件。 此外,您可以通过监控页面和上面提供的步骤检查批处理作业的状态。

如果检查调试日志,则可以找到列表大小,该大小指示已处理的记录数。

Limitations

我们一次只能处理5个批处理作业。 这是Batch Apex的限制之一。

使用Apex详细信息页面安排Apex批处理作业

您可以通过Apex详细页面安排Apex课程,如下所示 -

Step 1 - 转到设置⇒Apex类,单击Apex类。

从细节页面第1步中推出Apex

Step 2 - 单击Schedule Apex按钮。

从详细页面S2中推出Apex

Step 3 - 提供详细信息。

从细节页面S3uling Speuling Apex

使用可调度接口调度Apex批处理作业

您可以使用可调度接口安排Apex批处理作业,如下所示 -

// Batch Job for Processing the Records
global class CustomerProessingBatch implements Database.Batchable<sobject> {
   global String [] email = new String[] {'test@test.com'};
   // 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('test@test.com');//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);