Apex - Пакетная обработка
В этой главе мы разберемся с пакетной обработкой в Apex. Рассмотрим сценарий, при котором мы будем обрабатывать большое количество записей ежедневно, возможно, очищая данные или, возможно, удаляя некоторые неиспользуемые данные.
Что такое Batch Apex?
Пакетная обработка Apex - это асинхронное выполнение кода Apex, специально разработанное для обработки большого количества записей и обладающее большей гибкостью в ограничениях регулятора, чем синхронный код.
Когда использовать Batch Apex?
Если вы хотите обрабатывать большое количество записей ежедневно или даже в определенный промежуток времени, вы можете выбрать Batch Apex.
Кроме того, если вы хотите, чтобы операция была асинхронной, вы можете реализовать Batch Apex. Пакетная Apex представлена как интерфейс, который должен быть реализован разработчиком. Пакетные задания можно запускать программно во время выполнения с помощью Apex. Пакетная обработка Apex работает с небольшими пакетами записей, охватывая весь ваш набор записей и разбивая обработку на управляемые фрагменты данных.
Использование Batch Apex
Когда мы используем Batch Apex, мы должны реализовать предоставленный Salesforce интерфейс Database.Batchable, а затем программно вызвать класс.
Вы можете отслеживать класс, выполнив следующие действия:
Чтобы отслеживать или останавливать выполнение пакетного задания Apex Batch, выберите «Настройка» → «Мониторинг» → «Задания Apex» или «Задания» → «Задания Apex».
Интерфейс Database.Batchable имеет следующие три метода, которые необходимо реализовать:
- Start
- Execute
- Finish
Давайте теперь разберемся с каждым методом подробно.
Начало
Метод Start - один из трех методов интерфейса Database.Batchable.
Syntax
global void execute(Database.BatchableContext BC, list<sobject<) {}
Этот метод вызывается при запуске пакетного задания и собирает данные, с которыми будет работать пакетное задание.
Рассмотрим следующие моменты, чтобы понять метод -
Использовать Database.QueryLocatorobject, когда вы используете простой запрос для создания области объектов, используемых в пакетном задании. В этом случае ограничение на количество строк данных SOQL будет обойдено.
Используйте итеративный объект, когда у вас есть сложные критерии для обработки записей. Database.QueryLocator определяет объем записей, которые должны быть обработаны.
Выполнить
Давайте теперь разберемся с методом Execute интерфейса Database.Batchable.
Syntax
global void execute(Database.BatchableContext BC, list<sobject<) {}
где list <sObject <возвращается методом Database.QueryLocator.
Этот метод вызывается после метода Start и выполняет всю обработку, необходимую для пакетного задания.
Конец
Теперь мы обсудим метод Finish интерфейса Database.Batchable.
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[] {'[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});
}
}
Чтобы выполнить этот код, сначала сохраните его, а затем вставьте следующий код в Execute anonymous. Это создаст объект класса, а метод Database.execute выполнит пакетное задание. После завершения работы на указанный адрес электронной почты будет отправлено электронное письмо. Убедитесь, что у вас есть запись о клиенте,Active как проверено.
// Paste in Developer Console
CustomerProessingBatch objClass = new CustomerProessingBatch();
Database.executeBatch (objClass);
Как только этот класс будет выполнен, проверьте указанный вами адрес электронной почты, на который вы получите электронное письмо с информацией. Кроме того, вы можете проверить статус пакетного задания на странице «Мониторинг» и выполнить указанные выше действия.
Если вы проверите журналы отладки, вы можете найти размер списка, который указывает, сколько записей было обработано.
Limitations
Мы можем обрабатывать только 5 пакетных заданий одновременно. Это одно из ограничений Batch Apex.
Планирование пакетного задания Apex с помощью страницы сведений о Apex
Вы можете запланировать класс Apex на странице сведений о Apex, как показано ниже -
Step 1 - Перейдите в «Настройка» ⇒ «Классы Apex», нажмите «Классы Apex».
Step 2 - Щелкните кнопку Schedule Apex.
Step 3 - Сообщите подробности.
Планирование пакетного задания 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);