Create Batch Apex Job and Scheduled Apex to update Account related Contact Record field

Asynchronous apex jobs are executed when the resources are available. So any calling method which calls Asynchronous apex won’t wait for the outcome of the Asynchronous call. This is especially beneficial when we want to process bulk data and stay within the governor limits. The processing limit for asynchronous calls is also greater than that in the case of Synchronous jobs. Asynchronous Apex can be executed in the following manner.

  • Future Method
  • Batch Apex
  • Queueable Apex
  • Scheduled Apex

In this article, we will work learn about Batch Apex and Scheduled Apex. Check Interview Worthy Questions.

A batch apex class implements Database.Batchable and has three methods: Start, Execute (void type), and Finish (void type). The records are gathered in the start method using Query Locator in string data type. The processing happens in Execute method and the finish method is used for after-work to print the results, send email notifications, etc. We can also call another batch from the batch finish method. Similarly Scheduled Apex implements Schedulable and has one void type execute method.

Scenario: Update Company field on Contact Objects with Account Company name using batch apex. Save the success and failure results and schedule the job for every midnight at 12:01 a.m.

Batch Apex Class Code Snippet

  1. Go to developer console
  2. Click on File | New | Apex Job
  3. Name the class and paste below with same class name.
public class Accountconbatch implements Database.Batchable<sObject>,database.stateful {
    set<id> allIds=new set<id>();
    set<id> allFailedId=new set<id>();
    set<id> allSuccessId=new set<id>();
    integer totalSizeRecords=0;
    public Database.QueryLocator start(Database.BatchableContext bc){
        string accon = 'Select ID,Name,(Select Id,Company__c FROM CONTACTS) From Account';
        return Database.getQueryLocator(accon);
    }
    public void execute(Database.BatchableContext bc, list<Account> accon){
        totalSizeRecords+=accon.size();
        
        List<Contact> cUpdate = new List<Contact>();
        for(Account a : accon)
        { 
            for (Contact c:a.contacts){
                c.Company__c = a.Name; 
                cUpdate.add(c);
            }            
        }
        //Check if the list is empty
        if(cUpdate.size()>0) {
            //Use SaveResult to segregate success and failed results
            Database.SaveResult[] myresult= Database.update(cUpdate, false);
            
            for(Integer i=0; i< myresult.size(); i++){
                
                if(myresult.get(i).IsSuccess()){
                    system.debug('Success');
                    allSuccessId.add(myresult.get(i).id);
                }
                else if(!myResult.get(i).isSuccess()) {
                    Database.Error errors =  myResult.get(i).getErrors().get(0);
                    System.debug('Error Occurs While Processing The Record'+errors.getMessage());
                    allFailedId.add(myResult.get(i).Id);
                }
            }}}
    public void finish(Database.BatchableContext bc){
        //Printing the results
        system.debug('All fails Ids===> ' +allFailedId);
        system.debug('All success Id---> ' +allSuccessId);
        system.debug('Total number of records processed ==> ' +totalSizeRecords);
        
    }
    
}

Code Snippet to execute the Batch Job in Anonymous Window: (Execute immediately or after some minutes time)

  1. Go to developer console.
  2. Open execute anonymous window under Debug from the top bar.
  3. Run the below code.
Accountconbatch a = New Accountconbatch();
String jobID = database.executeBatch(a);
system.debug('jobID');

OR

database.executeBatch(new Accountconbatch());

We can also schedule it for later using: System.ScheduleBatch(a ,’Job Name’, minutes, scopeSize);
We can monitor the Batch Apex jobs under Apex Jobs in the Quick Find box.

Print under Debug Logs

Queried Results under Query Editor

Scheduled Apex Code Snippet

If we want to schedule the same batch job for timely execution, we can schedule it with Scheduled Apex

public class ScheduleJob implements Schedulable {
   public void execute(SchedulableContext SC)
    {

      //Execute Batch Job Under Scheduled Apex
        Accountconbatc a = new Accountconbatc();
        string jobid= Database.executeBatch(a);
        system.debug('jobid');
        
    }
}

Now, the Scheduled Apex can be scheduled via code or via the User interface as well.

Code to schedule Scheduled Job using Anonymous window:

Schedule sch = new Schedul();
// Seconds Minutes Hours Day_of_month Month Day_of_week optional_year 
string cron= '0 01 0 * * ?';
String jobID = system.schedule('Midnight Job', cron, sch);
system.debug('jobID');

The cron expression accounts for the chronology i.e the time, date, month setting of the Jobs.

We can schedule the same via the User interface under Schedule Apex under Apex Class.

Scheduled Apex

We can monitor these jobs under Scheduled Apex under the Quick find box as well.

Interview Worthy Questions

Batch apex and Scheduled class

Can we call a batch class from another batch class?

Yes, we can call one batch class from another batch class by calling it from its finish method.

Can we call a Future method from batch class?

No, we cannot directly call a future method from a batch class. But as a webservice can be called from batch class and a webservice can call a future method. So from the batch class, we can call the webservice and then call the required future method.

How can we do chaining of batch jobs?

We can chain the second batch class from the finish method of the first batch class.
We can also use the Queueable Apex for chaining the jobs.

How many active batches(running parallel) can be allowed at a time?

We can have five queued or active batch jobs at one time. The maximum number of batch Apex executions per 24-hour period is 2.5 lac or the number of user licenses in your org multiplied by 200—whichever is greater. 

How can we track or monitor the status of the currently running batch job?

The job Id returned by the batchable context variable can help track the status of a batch through AsyncApexJob.Status or under Apex Jobs as above explained.

Is it possible to do Synchronous Web service callouts from scheduled apex?

No, Synchronous Web service callouts are not supported from scheduled Apex. However, if the scheduled Apex executes a batch job, callouts are supported from the batch class.

Can we call the scheduler from the future method?

Yes

Can we modify the scheduler class or classes referenced by this scheduler class if any scheduled job is pending?

No. If there are one or more active scheduled jobs for an Apex class, we cannot update the class or any classes referenced by this class through the Salesforce user interface. But can delete the job under Scheduled Jobs to abort the job and then make the changes.

What are Apex Flex Queue?

Using the Flex Queues, we can queue up to 100 batch jobs that can be in the holding status. Jobs that are submitted for execution but are not processed immediately by the system go in the holding status and are placed in a separate queue (the Apex flex queue).

What is the minimum and maximum batch size?

The minimum size and maximum size for Batch Apex are 1 and 2000 respectively and by default is 200. We can optionally specify the scope size as Database.executeBatch(a,50);

What is the maximum number of batch classes allowed in Apex Flex Queue for execution?

100

What is Stateful Batch Apex?

Batch Apex is stateless by default. That means for each execution of your execute method, you receive a fresh copy of your object. Each execution of a batch Apex job is considered a discrete transaction. For example, a batch Apex job that contains 1,000 records and is executed without the optional scope parameter is considered five transactions of 200 records each.

If your batch process needs information that is shared across transactions, one approach is to make the Batch Apex class itself stateful by implementing the Stateful interface. If our batch job needs information that is shared across each transaction, this instructs Force.com IDE to preserve the values of your static and instance variables between transactions. It can be useful to take into account the number of processed records.

You can reference Salesforce documentation for more. And definitely shoot the doubts for discussion!

Leave a comment

error: Content is protected !!