Apex - Xử lý hàng loạt

Trong chương này, chúng ta sẽ hiểu về Xử lý hàng loạt trong Apex. Hãy xem xét một tình huống trong đó, chúng tôi sẽ xử lý một số lượng lớn các bản ghi hàng ngày, có thể là làm sạch dữ liệu hoặc có thể xóa một số dữ liệu không sử dụng.

Batch Apex là gì?

Batch Apex là thực thi không đồng bộ của mã Apex, được thiết kế đặc biệt để xử lý số lượng lớn các bản ghi và có tính linh hoạt cao hơn trong giới hạn thống đốc so với mã đồng bộ.

Khi nào thì sử dụng Batch Apex?

  • Khi bạn muốn xử lý số lượng lớn bản ghi hàng ngày hoặc thậm chí vào khoảng thời gian cụ thể thì bạn có thể sử dụng Batch Apex.

  • Ngoài ra, khi bạn muốn một hoạt động là không đồng bộ thì bạn có thể triển khai Batch Apex. Batch Apex được hiển thị như một giao diện phải được triển khai bởi nhà phát triển. Các công việc hàng loạt có thể được gọi theo chương trình trong thời gian chạy bằng Apex. Batch Apex hoạt động trên các loạt bản ghi nhỏ, bao gồm toàn bộ tập hợp bản ghi của bạn và chia nhỏ quá trình xử lý thành các phần dữ liệu có thể quản lý được.

Sử dụng Batch Apex

Khi chúng ta đang sử dụng Batch Apex, chúng ta phải triển khai Database.Batchable giao diện do Salesforce cung cấp, rồi gọi lớp theo chương trình.

Bạn có thể theo dõi lớp học bằng cách làm theo các bước sau:

Để giám sát hoặc dừng việc thực hiện công việc hàng loạt Apex Batch, hãy đi tới Thiết lập → Giám sát → Công việc Apex hoặc Công việc → Công việc Apex.

Giao diện Database.Batchable có ba phương pháp sau cần được triển khai:

  • Start
  • Execute
  • Finish

Bây giờ chúng ta hãy hiểu chi tiết từng phương pháp.

Khởi đầu

Phương thức Start là một trong ba phương thức của giao diện Database.Batchable.

Syntax

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

Phương thức này sẽ được gọi khi bắt đầu Công việc Hàng loạt và thu thập dữ liệu mà Công việc Hàng loạt sẽ hoạt động.

Hãy xem xét các điểm sau để hiểu phương pháp:

  • Sử dụng Database.QueryLocatorđối tượng khi bạn đang sử dụng một truy vấn đơn giản để tạo phạm vi đối tượng được sử dụng trong công việc hàng loạt. Trong trường hợp này, giới hạn hàng dữ liệu SOQL sẽ bị bỏ qua.

  • Sử dụng đối tượng có thể lặp lại khi bạn có các tiêu chí phức tạp để xử lý các bản ghi. Database.QueryLocator xác định phạm vi của các bản ghi sẽ được xử lý.

Hành hình

Bây giờ chúng ta hãy hiểu phương thức Execute của giao diện Database.Batchable.

Syntax

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

trong đó, list <sObject <được trả về bởi phương thức Database.QueryLocator.

Phương thức này được gọi sau phương thức Start và thực hiện tất cả các xử lý cần thiết cho Batch Job.

Hoàn thành

Bây giờ chúng ta sẽ thảo luận về phương thức Kết thúc của giao diện Database.Batchable.

Syntax

global void finish(Database.BatchableContext BC) {}

Phương thức này được gọi ở cuối và bạn có thể thực hiện một số hoạt động hoàn thiện như gửi email với thông tin về tình trạng và hồ sơ công việc hàng loạt đã xử lý.

Ví dụ về Batch Apex

Hãy để chúng tôi xem xét một ví dụ về Công ty Hóa chất hiện tại của chúng tôi và giả định rằng chúng tôi có yêu cầu cập nhật trường Trạng thái Khách hàng và Mô tả Khách hàng của Hồ sơ Khách hàng đã được đánh dấu là Hoạt động và có Ngày như hôm nay. Việc này phải được thực hiện hàng ngày và phải gửi email cho Người dùng về trạng thái của Xử lý hàng loạt. Cập nhật Trạng thái Khách hàng là 'Đã xử lý' và Mô tả Khách hàng là 'Đã cập nhật Thông qua Công việc Hàng loạt'.

// 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});
   }
}

Để thực thi mã này, trước tiên hãy lưu nó và sau đó dán mã sau vào Thực thi ẩn danh. Thao tác này sẽ tạo đối tượng của lớp và phương thức Database.execute sẽ thực hiện công việc Batch. Sau khi công việc hoàn thành, một email sẽ được gửi đến địa chỉ email được chỉ định. Đảm bảo rằng bạn có hồ sơ khách hàng cóActive như đã kiểm tra.

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

Khi lớp này được thực thi, hãy kiểm tra địa chỉ email bạn đã cung cấp, nơi bạn sẽ nhận được email với thông tin. Ngoài ra, bạn có thể kiểm tra trạng thái của công việc hàng loạt thông qua trang Giám sát và các bước như được cung cấp ở trên.

Nếu bạn kiểm tra nhật ký gỡ lỗi, thì bạn có thể tìm thấy kích thước Danh sách cho biết có bao nhiêu bản ghi đã được xử lý.

Limitations

Chúng tôi chỉ có thể xử lý 5 công việc hàng loạt cùng một lúc. Đây là một trong những hạn chế của Batch Apex.

Lên lịch công việc hàng loạt Apex bằng Trang chi tiết Apex

Bạn có thể lên lịch lớp Apex qua trang chi tiết Apex như dưới đây:

Step 1 - Vào Setup ⇒ Apex Classes, Click vào Apex Classes.

Step 2 - Bấm vào nút Schedule Apex.

Step 3 - Cung cấp thông tin chi tiết.

Lên lịch công việc hàng loạt Apex bằng giao diện có thể lập lịch

Bạn có thể lên lịch công việc hàng loạt Apex bằng Giao diện có thể lập lịch như được cung cấp bên dưới -

// 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);