Asynchronous Apex, we all know how sometimes Salesforce Governor Limit can haunt us at times. With the limited amount of resource available due to the multi tenant architecture, we have to restrict our self with the optimum usage of the resources. But what if we want to use the platform to its maximum limit, what if we want to do the process on huge volume of data.
To overcome the above-mentioned crisis, Salesforce Apex has provided us with the feature of Asynchronous Apex. To start with Asynchronous Apex provides us with the double governor limits in most of the cases and in some, we can perform a bulk operation on records up to 50 million.
There are lots of benefits of using Asynchronous Apex, but we are supposed to choose which Asynchronous apex would be the best way to reach our business goal.
How Asynchronous calls are handled by Salesforce’s Queue store and is then distributed to the application servers.
The above is depicting the Process-type(future, batch, and bulk API) wise distribution of the asynchronous processes which are then distributed to different application servers.
It is a method which runs on a separate thread in the background. It does not impact the performance of a running transaction as it carried out in a different context. We use this method for the execution of long running operation such as a web call out where we are not sure when the response will come or whether a response will come or not.
This is not the only use case of the future method we also use them to isolate DML statement because there is a possibility that when two DML operation is performed over different sObject then we might get a mixed DML operation error. Future methods help us in preventing this error.
The specialty of the Future method is that it executes when the resources are available and does not out overhead on the server. This is the reason that execution of the code does not have to wait for the completion of a long running operation and also we get higher Governor limits when we use Asynchronous Apex.
Some consideration before we start implementing the future method is that it should be declared as a static method and the only return type it can have is void. Secondly, the parameter defined for the future method must be primitive i.e. no salesforce sObject can be passed as a parameter to the future method. The reason an sObject is not passed in the future method is that there is a possibility that the sent sObject might change between the time the future method is executed.
To interact future method with the sObject that already exists in the database, we can pass the ID of the object instead and then fetch the latest version of the record in the method itself and then perform the task, as shown below.
Below is a skeletal code of a future method that interacts with an external web service. For this we have to add an extra annotation to the method to make the platform aware that this method will interact with an external service, as shown below
Future methods are invoked as any other method in the apex, but a Future method cannot invoke another future method. There are certain limitations of the future methods in addition to the above-mentioned limitation which are given below:
No more than 50 methods with Future annotation can be called in a single apex invocation.
Maximum 250000 invocation is allowed per rolling 24-hours or number of licenses multiplied by 200 whichever is the greatest is the limit of the invocation. This limit is for the entire organization and is shared with the entire Asynchronous apex, i.e. Batch Apex, Queueable Apex and scheduled Apex.
Since Future method is called in different context then the running thread, it has to be tested in a different way than the normal. To make them run in the same context we make use of startTest() and stopTest() code block. All asynchronous method written after the startTest are collected by the system and are executed synchronously after the stopTest method is called, as shown below.
@isTestprivate class ClassNameOfFutureMethodTest { @isTest static void test1() { Test.startTest(); ClassNameOfFutureMethod.FuturemethoName (); Test.stopTest(); } // Verify the result with help of system.assertEquals }}
Queueable Apex is also a way of running Apex jobs asynchronously and to make a class Queueable we need to implement an interface i.e. Queueable interface. With the help of this interface, we can queue jobs and also monitor them, this is an enhanced way of running the asynchronous process as compared to the future method.
Queueable jobs are similar to the future method as both are queued before the execution and get executed only after the resources are available, but the extra feature it offers is below:
Queueable jobs implements the Queueable interface, in this interface we have an execute method which has return type of void and take QueueableContext as a parameter. Below is an example of implementation of the Apex Queueable job:
In order to add this class to the queue list, we need to make use of SystemEnqueueJob, these methods return an Id. With help of this Id, we can monitor its progress and check its status.
As we know that Queueable is an asynchronous job, therefore to test these classes we have to make use of the startTest and StopTest methods, where all the asynchronous method runs synchronously. Below is an example of the Queueable job and the way to test it.
There is a possibility that we want to perform a certain task after the completion of another job. As discussed before, we can call another Queueable Job from inside of a running queueable job. To do this we need to add another job to the queue in the execute method of the presently running job. We achieve this as shown below.
To make a class invocable at a specific time, first, we need to implement Schedulable interface in the class and then schedule it either from Salesforce UI or from the system.schedule method.
To invoke a class on a regular basis we first need to implement the Schedulable interface, which like Queueable apex has an execute method. The scheduler run as system and user permission has no significance in executing the class.
As mentioned above, while implementing schedulable interface we need to implement the execute method of the interface which is a global method and takes schedulableContext as an argument, its syntax is given below.
The next method is used to schedule the class it is called system.schedule, as shown below.
Batch can also be schedule using the method system.schedulebatch, about this we will study in detail in later section.
Once the job is scheduled we can keep track of it with the help of schedulableContext, with help of its getTriggerID we can retrieve the Id of the scheduled job and we can query the CronTrigger Object and monitor the progress of the job.
The difference between the two ways is that in the system.schedule method we can also specify the minutes and seconds as well but using the UI we can just mention the hour of the day.
Then there are some special characters which are used in conjunction with the values like ‘*’, ‘?’, “,”,’-‘
Salesforce Governor limits us to build a long running process like data cleansing or data archiving, where records more than 50000 are being processed at one time. To fulfill this requirement Salesforce has to introduce the batch Apex, a batch job makes smaller chunks of the data which is known as batch size and then asynchronously work on each batch in a separate thread and therefore not hitting the governor limit.
A batch job can be invoked at runtime programmatically using apex and it can also be scheduled using a scheduled job as discussed above.
A Class to be executed as a Batch has to implement the batchable interface. In this interface, we have to implement three methods, i.e Start, execute and finish methods.
To collect the records on which we have to perform the bulk processing tasks are collected in this method, this method returns an iterable or a Database.querylocator, both of the return types have their use cases but mostly Database.querylocator is used.
When a simple query is used to generate the collections of record, we should use database.querylocator. This object by passes the Salesforce governor limit of 50000 records and can return up to 50 million records in an org.
Iterable is created only when we have to create a complex scope or collection of records, Iterable is limited to 50000 records only.
After the collections of record is gathered the execute method is then next executed. This method is called for each batch, it takes a reference to database.BatchableContext object and a list of sObject. Batches are normally executed in the order they are received, but their execution order is not guaranteed.
Once all the batches are executed, then the last method Finish is called. This method takes the batchable context as a parameter and is used to perform post processing task like sending an email.
Each batch is considered as a separate transaction and they avail fresh set of apex governor limit, i.e. if a batch of 500 records are being processed with scope of 50 then 10 batches are going to be executed separately and the governor limits will reset for each batch.
To Allow Callout in the batch class we need it to implement another interface i.e. Database.AllowsCallouts
Each batch execution is a different transaction and one transaction is unaware about the status and progress of the other transaction. The entire batch executed are asynchronous process and do not have a state after they have finished executing. To maintain the state and pass a value from one batch to another we need to specify another interface while defining the class, i.e. Database.Stateful.
Mock Interview Questions on Batch Apex
In batches, If the first transaction succeeds but the second fails, the database updates made in the first transaction are not rolled back.
Calling a future method is not allowed in the Execute method, But a web service can be called. A web service can also call an @future method. So, we can define a web service having a future method invocation and call the web service from the execute method of Batch Job.
Q. 7 Can a future method call another non-future method to process tasks like callouts, and have those methods return data to the future method for further processing?
In Iterable
While working on the Salesforce application, we store huge data in our org and it will keep growing year by year. If we have to run some job that will take some time then in the case of synchronous apex we will get the limit error, heap size error, or timeout error. To avoid such issues, we can do those long-running or time-consuming operations using Asynchronous apex which will run in a separate thread and will not impact the main thread. So Asynchronous Apex is used to run the process in a separate thread at a later time.
Finish – Finish method is used to send email or call a different batch job or do nothing.
Future method is used to run the process in a separate thread at a later point of time(when resources are available). For example, you can use the future annotation when making an asynchronous Web service callout to an external service. Without the annotation, the Web service callout is made from the same thread that is executing the Apex code, and no additional processing can occur until the callout is complete (synchronous processing).
We can launch other Batchjob from finish method of the first job. This is called batch job chaining.
Query locator is used in Start method of Batch apex and it gives the ability to process upto 50 million records.
When we have large volumes of data and do not require business logic to be processed in realtime we can use or implement Batch apex. We can process upto 50 million records using Batch Apex.
What is Rollup Summary?
Rollup Summary is used to display the count of child records and calculate the sum,minimum and maximum of child records.
The next method is used to schedule the class it is called system.schedule, as shown below.
When a simple query is used to generate the collections of record, we should use database.querylocator. This object by passes the Salesforce governor limit of 50000 records and can return up to 50 million records in an org.
A batch job can be invoked at runtime programmatically using apex and it can also be scheduled using a scheduled job as discussed above.
There is a possibility that we want to perform a certain task after the completion of another job. As discussed before, we can call another Queueable Job from inside of a running queueable job. To do this we need to add another job to the queue in the execute method of the presently running job. We achieve this as shown below.
As we know that Queueable is an asynchronous job, therefore to test these classes we have to make use of the startTest and StopTest methods, where all the asynchronous method runs synchronously. Below is an example of the Queueable job and the way to test it.
FAQ
What is asynchronous in Apex?
What is difference between synchronous and asynchronous apex in Salesforce?
How can we implement asynchronous process in Apex?
…
NOTES:-
- The future method must be static.
- It only returns void type.
- It allows callout when (callout = true) is specified.
What are different types of asynchronous methods we have in Salesforce?
- Future methods.
- Batch Apex.
- Queueable Apex.
- Scheduled Apex.