Asynchronous Apex in Salesforce
Asynchronous Apex is used to run processes in a separate thread, at a later time.
An asynchronous process is a process or function that executes a task "in the background" without the user having to wait for the task to finish.
Here’s a real-world example. Let’s say you have a list of things to accomplish before your weekly Dance Revolution practice. Your car is making a funny noise, you need a different color hair gel and you have to pick up your uniform from your mom’s house. You could take your car to the mechanic and wait until it is fixed before completing the rest of your list (synchronous processing), or you could leave it there and get your other things done, and have the shop call you when it’s fixed (asynchronous processing). If you want to be home in time to iron your spandex before practice, asynchronous processing allows you to get more stuff done in the same amount of time without the needless waiting.
Increased Governor and Execution Limits:
One of the main benefits of running asynchronous Apex is higher governor and execution limits. For example, the number of SOQL queries is doubled from 100 to 200 queries when using asynchronous calls. The total heap size and maximum CPU time are similarly larger for asynchronous calls.
Not only do you get higher limits with async, but also those governor limits are independent of the limits in the synchronous request that queued the async request initially. That’s a mouthful, but essentially, you have two separate Apex invocations, and more than double the processing capability. This comes in handy for instances when you want to do as much processing as you can in the current transaction but when you start to get close to governor limits, continue asynchronously.
Types of Asynchronous Apex :
- Future Methods
- Queueable Apex
- Batch Apex
- Scheduled Apex
1. Future Methods:
Future Apex is used to run processes in a separate thread, at a later time when system resources become available.Things to Remember:
- Methods are annotated with @future annotation.
- Use the future annotation to specify that these methods that are executed asynchronously.
- Methods with future annotation must be static methods.
- Methods with future annotation can only return a void type.
- The specified parameters must be primitive data types, arrays of primitive data types, or collections of primitive data types.
- Future methods are not guaranteed to execute in the same order as they are called.
- When using future methods, it’s also possible that two future methods could run concurrently, which could result in record locking and a nasty runtime error if the two methods were updating the same record.
- Methods with the future annotation must be static methods, and can only return a void type.
- The specified parameters must be primitive data types, arrays of primitive data types, or collections of primitive data types; future methods can’t take objects as arguments.
- Future methods won’t necessarily execute in the same order they are called. In addition, it’s possible that two future methods could run concurrently, which could result in record locking if the two methods were updating the same record.
- Future methods can’t be used in Visualforce controllers in getMethodName(), setMethodName(), nor in the constructor.
- You’re limited to 50 future calls per Apex invocation, and there’s an additional limit on the number of calls in a 24-hour period. For more information on limits, see the link below.
# Future Method Syntax:
Future methods must be static methods, and can only return a void type. The specified parameters must be primitive data types, arrays of primitive data types, or collections of primitive data types. Notably, future methods can’t take standard or custom objects as arguments. A common pattern is to pass the method a List of record IDs that you want to process asynchronously.
public class MyClass {
@future
public static void myFutureMethod(List<Id> recordIds) {
List<Account> accounts = [Select Id, Name from Account Where Id IN :recordIds];
// Your code here
}
}
2. Queueable Apex:
Queueable Apex allows you to submit jobs for asynchronous processing similar to future methods with the following additional benefits:
- Non-primitive types: Your Queueable class can contain member variables of non-primitive data types, such as sObjects or custom Apex types. Those objects can be accessed when the job executes.
- Monitoring: When you submit your job by invoking the System.enqueueJob method, the method returns the ID of the AsyncApexJob record. You can use this ID to identify your job and monitor its progress, either through the Salesforce user interface in the Apex Jobs page, or programmatically by querying your record from AsyncApexJob.
- Chaining jobs: You can chain one job to another job by starting a second job from a running job. Chaining jobs is useful if you need to do some sequential processing.
Things to Remember:
- The execution of a queued job counts once against the shared limit for asynchronous Apex method executions.
- You can add up to 50 jobs to the queue with System.enqueueJob in a single transaction.
- When chaining jobs, you can add only one job from an executing job with System.enqueueJob, which means that only one child job can exist for each parent queueable job. Starting multiple child jobs from the same queueable job is a no-no.
- No limit is enforced on the depth of chained jobs, which means that you can chain one job to another job and repeat this process with each new child job to link it to a new child job. However, for Developer Edition and Trial orgs, the maximum stack depth for chained jobs is 5, which means that you can chain jobs four times and the maximum number of jobs in the chain is 5, including the initial parent queueable job.
# Queueable Syntax:
To use Queueable Apex, simply implement the Queueable interface.
public class MyClass implements Queueable {
public void execute(QueueableContext context) {
// Your code here
}
}
3. Batch Apex:
Batch Apex is used to run large jobs (think thousands or millions of records!) that would exceed normal processing limits. Using Batch Apex, you can process records asynchronously in batches (hence the name, “Batch Apex”) to stay within platform limits. If you have a lot of records to process, for example, data cleansing or archiving, Batch Apex is probably your best solution.
This functionality has two awesome advantages:
- Every transaction starts with a new set of governor limits, making it easier to ensure that your code stays within the governor execution limits.
- If one batch fails to process successfully, all other successful batch transactions aren’t rolled back.
# Batch Apex Syntax:
To write a Batch Apex class, your class must implement the Database.Batchable interface and include the following three methods:
start:
- Used to collect the records or objects to be passed to the interface method execute for processing. This method is called once at the beginning of a Batch Apex job and returns either a Database.QueryLocator object or an Iterable that contains the records or objects passed to the job.
- Most of the time a QueryLocator does the trick with a simple SOQL query to generate the scope of objects in the batch job. But if you need to do something crazy like loop through the results of an API call or pre-process records before being passed to the execute method, you might want to check out the Custom Iterators link in the Resources section.
- With the QueryLocator object, the governor limit for the total number of records retrieved by SOQL queries is bypassed and you can query up to 50 million records. However, with an Iterable, the governor limit for the total number of records retrieved by SOQL queries is still enforced.
execute:
Performs the actual processing for each chunk or “batch” of data passed to the method. The default batch size is 200 records. Batches of records are not guaranteed to execute in the order they are received from the start method.
This method takes the following:
- A reference to the Database.BatchableContext object.
- A list of sObjects, such as List<sObject>, or a list of parameterized types. If you are using a Database.QueryLocator, use the returned list.
finish:
Used to execute post-processing operations (for example, sending an email) and is called once after all batches are processed.
public class MyBatchClass implements Database.Batchable<sObject> {
public (Database.QueryLocator | Iterable<sObject>) start(Database.BatchableContext bc) {
// collect the batches of records or objects to be passed to execute
}
public void execute(Database.BatchableContext bc, List<P> records){
// process each batch of records
}
public void finish(Database.BatchableContext bc){
// execute any post-processing operations
}
}
4. Scheduler Apex:
The Apex Scheduler lets you delay execution so that you can run Apex classes at a specified time. This is ideal for daily or weekly maintenance tasks using Batch Apex. To take advantage of the scheduler, write an Apex class that implements the Schedulable interface, and then schedule it for execution on a specific schedule.
Scheduling a Job from the UI
- You can also schedule a class using the user interface.
- From Setup, enter Apex in the Quick Find box, then select Apex Classes.
- Click Schedule Apex.
- For the job name, enter something like Daily Reminder.
- Click the lookup button next to Apex class and enter * for the search term to get a list of all classes that can be scheduled. In the search results, click the name of your scheduled class.
- Select Weekly or Monthly for the frequency and set the frequency desired.
- Select the start and end dates, and a preferred start time.
- Click Save.
Things to Remember:
- You can only have 100 scheduled Apex jobs at one time and there are maximum number of scheduled Apex executions per a 24-hour period. See Execution Governors and Limits in the Resources section for details.
- Use extreme care if you’re planning to schedule a class from a trigger. You must be able to guarantee that the trigger won’t add more scheduled jobs than the limit.
- Synchronous Web service callouts are not supported from scheduled Apex. To be able to make callouts, make an asynchronous callout by placing the callout in a method annotated with @future(callout=true) and call this method from scheduled Apex. However, if your scheduled Apex executes a batch job, callouts are supported from the batch class.
# Scheduled Apex Syntax:
To invoke Apex classes to run at specific times, first implement the Schedulable interface for the class. Then, schedule an instance of the class to run at a specific time using the System.schedule method.
public class MyClass implements Schedulable {
public void execute(SchedulableContext ctx) {
// Your code here
}
}
Resources:
# Execution Governors and Limits
# Trailhead: Asynchronous Apex
# Future Methods
# Queueable Apex
# Batch Apex
# Scheduler Apex
Comments
Post a Comment