Apex - Elaborazione batch

In questo capitolo capiremo l'elaborazione in batch in Apex. Considera uno scenario in cui elaboreremo un gran numero di record su base giornaliera, probabilmente la pulizia dei dati o forse l'eliminazione di alcuni dati inutilizzati.

Cos'è Batch Apex?

Batch Apex è l'esecuzione asincrona del codice Apex, appositamente progettato per l'elaborazione di un gran numero di record e ha una maggiore flessibilità nei limiti del governor rispetto al codice sincrono.

Quando utilizzare Batch Apex?

  • Quando si desidera elaborare un numero elevato di record su base giornaliera o anche in un intervallo di tempo specifico, è possibile utilizzare Batch Apex.

  • Inoltre, quando si desidera che un'operazione sia asincrona, è possibile implementare Batch Apex. Batch Apex è esposto come un'interfaccia che deve essere implementata dallo sviluppatore. I processi batch possono essere richiamati a livello di codice in fase di esecuzione utilizzando Apex. Batch Apex opera su piccoli batch di record, coprendo l'intero set di record e suddividendo l'elaborazione in blocchi di dati gestibili.

Utilizzo di Batch Apex

Quando si utilizza Batch Apex, è necessario implementare l'interfaccia Database.Batchable fornita da Salesforce, quindi richiamare la classe a livello di codice.

Puoi monitorare la classe seguendo questi passaggi:

Per monitorare o interrompere l'esecuzione del lavoro batch Apex batch, andare a Configurazione → Monitoraggio → Lavori Apex o Lavori → Lavori Apex.

L'interfaccia Database.Batchable ha i seguenti tre metodi che devono essere implementati:

  • Start
  • Execute
  • Finish

Vediamo ora di comprendere ogni metodo in dettaglio.

Inizio

Il metodo Start è uno dei tre metodi dell'interfaccia Database.Batchable.

Syntax

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

Questo metodo verrà richiamato all'avvio del lavoro batch e raccoglie i dati su cui opererà il lavoro batch.

Considera i seguenti punti per comprendere il metodo:

  • Utilizzare il Database.QueryLocatoroggetto quando si utilizza una query semplice per generare l'ambito degli oggetti utilizzati nel lavoro batch. In questo caso, il limite di righe di dati SOQL verrà ignorato.

  • Utilizzare l'oggetto iterabile quando si dispone di criteri complessi per elaborare i record. Database.QueryLocator determina l'ambito dei record che devono essere elaborati.

Eseguire

Vediamo ora di comprendere il metodo Execute dell'interfaccia Database.Batchable.

Syntax

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

dove, list <sObject <viene restituito dal metodo Database.QueryLocator.

Questo metodo viene chiamato dopo il metodo Start ed esegue tutta l'elaborazione richiesta per il lavoro batch.

finire

Discuteremo ora il metodo Finish dell'interfaccia Database.Batchable.

Syntax

global void finish(Database.BatchableContext BC) {}

Questo metodo viene chiamato alla fine e puoi completare alcune attività come l'invio di un'e-mail con le informazioni sui record del lavoro batch elaborati e lo stato.

Esempio di apice in batch

Consideriamo un esempio della nostra azienda chimica esistente e supponiamo di avere l'obbligo di aggiornare il campo Stato cliente e Descrizione cliente dei record cliente che sono stati contrassegnati come attivi e che hanno creato la data come oggi. Questa operazione dovrebbe essere eseguita quotidianamente e un'e-mail dovrebbe essere inviata a un utente sullo stato dell'elaborazione in batch. Aggiorna lo stato del cliente come "Elaborato" e la descrizione del cliente come "Aggiornato tramite lavoro batch".

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

Per eseguire questo codice, salvarlo prima e poi incollare il codice seguente in Esegui anonimo. Questo creerà l'oggetto della classe e il metodo Database.execute eseguirà il lavoro Batch. Una volta completato il lavoro, verrà inviata un'e-mail all'indirizzo e-mail specificato. Assicurati di avere un record del cliente che haActive come controllato.

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

Una volta eseguita questa lezione, controlla l'indirizzo email che hai fornito dove riceverai l'email con le informazioni. Inoltre, è possibile controllare lo stato del lavoro batch tramite la pagina Monitoraggio e i passaggi forniti sopra.

Se controlli i log di debug, puoi trovare la dimensione dell'elenco che indica quanti record sono stati elaborati.

Limitations

Possiamo avere solo 5 elaborazioni batch alla volta. Questo è uno dei limiti di Batch Apex.

Pianificazione del lavoro batch Apex utilizzando la pagina dettagli Apex

Puoi programmare la lezione Apex tramite la pagina dei dettagli Apex come indicato di seguito:

Step 1 - Vai a Configurazione ⇒ Classi Apex, fai clic su Classi Apex.

Step 2 - Fare clic sul pulsante Schedule Apex.

Step 3 - Fornire dettagli.

Pianificazione del lavoro batch Apex utilizzando l'interfaccia pianificabile

È possibile pianificare il lavoro batch Apex utilizzando l'interfaccia pianificabile come indicato di seguito:

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