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.<\/p>\n
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.<\/p>\n
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.<\/p>\n
<\/p>\n
Image Source: https:\/\/developer.salesforce.com\/page\/Asynchronous_Processing_in_Force_com<\/a><\/p>\n How Asynchronous calls are handled by Salesforce\u2019s Queue store and is then distributed to the application servers.<\/p>\n There are 4 Asynchronous Apex features their name and use cases are mentioned below:-<\/p>\n Image Source: https:\/\/developer.salesforce.com\/page\/Asynchronous_Processing_in_Force_com<\/a><\/p>\n The above Image is depicting the Process-type(future, batch, and bulk API) wise distribution of the asynchronous processes which are then distributed to different application servers.<\/p>\n Now we will discuss each of these features in detail:-<\/p>\n 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.<\/p>\n 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.<\/p>\n Image: Depicting the difference in thread processing between apex normal transaction and in future method<\/p>\n 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.<\/p>\n Simple syntax of the future method is mentioned below:<\/p>\n Global class ClassNameOfFutureMethod<\/p>\n {<\/p>\n @Future<\/strong><\/p>\n Public static void<\/strong> FuturemethoName()<\/p>\n {<\/p>\n \u00df Code to be executed \u00e0<\/p>\n }<\/p>\n }<\/p>\n 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.<\/p>\n 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.<\/p>\n global class ClassNameOfFutureMethod<\/p>\n {<\/p>\n \u00a0\u00a0\u00a0 @future<\/strong><\/p>\n public static void<\/strong> FuturemethoName (List<ID> rIds)<\/p>\n {<\/p>\n \/\/ We can get the records based on the list of Ids<\/p>\n List<custObj> obj = [SELECT Name FROM custObj WHERE Id IN : rIds];<\/p>\n \/\/ We can Process records after fetching the records<\/p>\n }<\/p>\n }<\/p>\n 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<\/p>\n global class ClassNameOfFutureMethod<\/p>\n {<\/p>\n \u00a0\u00a0\u00a0 @future(callout=true)<\/strong><\/p>\n public static void FuturemethoName (List<ID> rIds)<\/p>\n {<\/p>\n \/\/ We can get the records based on the list of Ids<\/p>\n List<custObj> obj = [SELECT Name FROM custObj WHERE Id IN : rIds];<\/p>\n \/\/ We can Process records after fetching the records<\/p>\n }<\/p>\n }<\/p>\n 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:<\/p>\n No more than 50 methods with Future annotation can be called in a single apex invocation.<\/p>\n 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.<\/p>\n 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.<\/p>\n @isTestprivate class ClassNameOfFutureMethodTest {\u00a0\u00a0\u00a0 @isTest static void test1() {\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Test.startTest();\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ClassNameOfFutureMethod.FuturemethoName ();\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Test.stopTest();\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ Verify the result with help of system.assertEquals\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }}<\/p>\n Salesforce implements a queue based framework for the handling of the asynchronous processes, the queue is implied to balance the load of request across organizations, following are the best practice for the future methods:<\/p>\n Next, we will discuss the Queueable Apex<\/p>\n 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.<\/p>\n 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:<\/p>\n 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:<\/p>\n public class QueueableClass implements Queueable {<\/p>\n public void execute(QueueableContext context) {<\/p>\n contact con = new contact(lastName=’Datta’,Phone=’9999999999′);<\/p>\n insert con;<\/p>\n }<\/p>\n }<\/p>\n 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.<\/p>\n ID queuejobID = System.enqueueJob(new QueueableClass());<\/p>\n AsyncApexJob queuejobInfo = [SELECT Status,NumberOfErrors FROM AsyncApexJob WHERE Id=: queuejobID];<\/p>\n 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.<\/p>\n @isTest<\/p>\n public class QueueableClass Test {<\/p>\n static testmethod void test1() {<\/p>\n Test.startTest();<\/p>\n System.enqueueJob(new AsyncExecutionExample());<\/p>\n Test.stopTest();<\/p>\n Contact con = [SELECT lastName,Phone FROM Contact WHERE lastName =’Datta’ LIMIT 1];<\/p>\n System.assertNotEquals(null, con);<\/p>\n System.assertEquals(‘9999999999’, con.Phone);<\/p>\n }<\/p>\n }<\/p>\n 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.\u00a0 We achieve this as shown below.<\/p>\n public class QueueableClass implements Queueable {<\/p>\n public void execute(QueueableContext context) {<\/p>\n contact con = new contact(lastName=’Datta’,Phone=’9999999999′);<\/p>\n insert con;<\/p>\n System.enqueueJob(new anotherQueueableJobClass());<\/p>\n }<\/p>\n }<\/p>\n Now we will discuss Apex Scheduler<\/p>\n 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.<\/p>\n 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.<\/p>\n 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.<\/p>\n global\u00a0void\u00a0execute(SchedulableContext\u00a0sc){}<\/p>\n This method is used to instantiate the class we want to schedule, as shown below.<\/p>\n global class MyScheduleClass implements Schedulable {<\/p>\n global void execute(SchedulableContext SC) {<\/p>\n Class2beSchedule M = new Class2beSchedule ();<\/p>\n }<\/p>\n }<\/p>\n The next method is used to schedule the class it is called system.schedule, as shown below.<\/p>\n MyScheduleClass m = new MyScheduleClass ();<\/p>\n String CronExpression = ’20 30 8 10 2 ?’;<\/p>\n String SchedulejobID = system.schedule(‘My Job’, CronExpression, m);<\/p>\n The schedulable class can also be used to Schedule a batch class, as shown below.<\/p>\n global class MyScheduleClass implements Schedulable {<\/p>\n global void execute(SchedulableContext SC) {<\/p>\n batchclass M = new batchclass ();<\/p>\n database.executeBatch(M);<\/p>\n }<\/p>\n }<\/p>\n Batch can also be schedule using the method system.schedulebatch, about this we will study in detail in later section.<\/p>\n 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.<\/p>\n To schedule a class we discussed that\u00a0 there are two ways:<\/p>\n 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.<\/p>\n Schematics of how to schedule a class from UI<\/p>\n Step 1:<\/p>\n Step 2: To schedule weekly<\/p>\n To Schedule Monthly<\/p>\n Let’s discuss how to create a cron expression:<\/p>\n Basic syntax of cron expression is<\/p>\n S M H DOM Mon DOW Yr<\/p>\n S- Seconds<\/p>\n M- Minutes<\/p>\n H- Hour<\/p>\n DOM- Day_of_month<\/p>\n Mon- month<\/p>\n DOW-Day_of_week<\/p>\n Yr -Year<\/p>\n Then there are some special characters which are used in conjunction with the values like \u2018*\u2019, \u2018?\u2019, \u201c,\u201d,\u2019-\u2018<\/p>\n Some sample cron Expressions are mentioned below:<\/p>\n\n
<\/p>\n
Asynchronous Apex: Future Method<\/h1>\n
<\/p>\n
Testing Future Methods<\/h2>\n
Best practice and performance for Future method<\/h2>\n
\n
Asynchronous Apex: Queueable Apex<\/h1>\n
<\/p>\n
\n
<\/p>\n
Testing Queueable Jobs<\/h2>\n
Chaining the Jobs<\/h2>\n
Limitations of Queueable Jobs<\/h2>\n
\n
Asynchronous Apex:\u00a0Apex Scheduler<\/h1>\n
Implementing the Interface schedulable<\/h2>\n
\n
<\/p>\n
<\/p>\n
<\/p>\n