Asynchronous Apex
Asynchronous Apex in Salesforce is used for executing operations that might take a long time, need to be processed in the background, or require higher limits than synchronous Apex. It allows for efficient handling of tasks like callouts to external services, batch processing of records, or handling complex business logic.
Types of Asynchronous Apex:
Future Methods :
Run in their own thread and do not start until resources are available.
Common use-case : Web service call out.
These method must be static
We can only pass primitive data type but not nonprimitive data type like sObject and Object.
Primitive Data Types:
- String, Integer, Decimal, Double, Boolean, Long ,Date, Time, DateTime
Collections of Primitives:
List<String>Set<Id>Map<String, Integer>
Serializable Objects:
BlobCustom Apex classes that implement the
Serializableinterface.
Batch Apex :
Run large jobs that would exceed normal processing limit.
Common use-case : Data cleansing or Archiving purpose.
Queueable Apex :
- Quable apex is extension of future method. It provide additional job chaining and allow more complex data type to be used.
Schedule Apex :
- Schedule apex to run at a specified time.
Future Methods
- FuturePracticeClass
public class FuturePracticeClass {
@future
public static void futureDemo() {
System.debug('Future method called');
for (Integer i = 0; i <= 10000; i++) {}
System.debug('Future method calling finished');
}
}
- Anonymous Window
System.debug('Ano Start');
FuturePracticeClass.futureDemo();
System.debug('Ano End');
Queueable Apex
Queueable Apex in Salesforce is a powerful asynchronous execution framework that allows developers to run Apex code in the background. It is more advanced and flexible than future methods and provides better control and chaining capabilities.
Key Features of Queueable Apex:
Asynchronous Processing: Runs Apex logic in the background, freeing up system resources for user-facing operations.
Job Chaining: You can enqueue another queueable job from within a running queueable job, allowing sequential processing.
Enhanced Debugging: Supports the use of non-primitive types (like custom objects) and allows chaining for debugging.
Execution Context: Executes in its own transaction, independent of the initiating transaction.
Queueable Apex:
Called by System.enqueueJob() method.
enqueueJob() return a Job ID that can be monitored.
Works beyond primitive argument.
When to Use Queueable Apex:
When you need to handle long-running operations without blocking the main thread.
When you require chaining multiple jobs for sequential processing.
When you need larger governor limits than synchronous operations.
Governer Limits
A transaction can only have 50 queued jobs at a time.
Queueable jobs are limited to 5 level of chaining
1. "A transaction can only have 50 queued jobs at a time."
- This means that within a single transaction, you can enqueue (add) a maximum of 50 Queueable jobs using
System.enqueueJob. If you try to enqueue more than 50 jobs, Salesforce will throw a LimitException.
for (Integer i = 0; i < 60; i++) {
System.enqueueJob(new MyQueueableJob()); // Enqueue a Queueable job
}
In this case:
The first 50 jobs will be enqueued successfully.
On the 51st job, Salesforce will throw a LimitException, because you exceeded the limit of 50 jobs in a single transaction.
2. "Queueable jobs are limited to 5 level of chaining."
- Queueable Apex allows for 5 levels of chaining. This means that a Queueable job can enqueue up to 5 additional jobs, creating a chain.
Code:
- QueueablePractice
public with sharing class QueueablePractice implements Queueable {
List<Account> accountList = null;
Id parentId = null;
public QueueablePractice(List<Account> accountList, Id parentId) {
this.parentId = parentId;
this.accountList = accountList;
}
public void execute(QueueableContext context) {
for (Account account : accountList) {
account.ParentId = parentId;
}
try {
update accountList;
System.debug('Account updated');
} catch (Exception e) {
System.debug(e.getMessage());
}
}
}
- Developer Console
List<Account> accountList = [SELECT Id, ParentId FROM Account WHERE Name = 'Update'];
QueueablePractice obj = new QueueablePractice(accountList, '001WU00000RiV7cYAF');
Id jobId = System.enqueueJob(obj);
System.debug('Job Id ' + jobId);
Batch Apex
Batch apex runs large jobs. It process thousands or millions of records
It process records asynchronously in batches
For Data cleansing or archiving, batch apex is probably the best solution.
For example you have 1000 records to be processed all of these wont be processed all together they will be processed in different different batche sizes. Default batch size is 200
So if you query 1000 records those 1k records will be divided in 5 pieces of 200 each. First 200 record will be processed then after that 200 and so on.
How batch apex works:
The execution logic of the batch class is called once for each batch of records that is being processed
Each time when a batch class is invoked the job is placed on apex job queue and is executed as discrete transaction.
Advantages :
Every transaction starts with a new set of governor limit.
If one batch fails to process successfully, then all other successful batch transactions are'nt rolled back.
Syntax:
Batch apex must implement the Database.Batchable interface and include the following three methods:
Start
Execute
Finish
Can we increase batch size/limit?
- We can increase batch limit/size. Yes we can but max is 2000 default is 200 and min is 1.
Methods in Batch
- Start method
Collects the records or objects to be passed to the interface method executing for processing.
Start() method is called at the beginning of batch apex job.
Entire batch apex it will be called once.
It returns a Database.QueryLocator object or an Iterable that contains the records or objects passed to the job.
When QueryLocator object is used, the governor limit for the total number of records retrived by SOQL queries is bypassed and 50 Million records can be queried.
Where as with an Iterabl, governer limit by SOQL is enforced
- Execute method
Perform actual processing for each batch of data passed.
Default batch size is 200.
Batches of records can be executed in any order, It does'nt depends on which order they are received from start method.
- Finish method
Execute post processing operation.
Calls once when all batches are processed.
For Example : Sending an email process can be implemented in finish method.
Invoke a batch:
MyBatch mybatch = new MyBatch(); Id batchId = Database.executeBatch(mybatch);
Id batchId = Database.executeBatch(mybatch, 100) // second paramter is the size of batch
Database.getQueryLocator()
Database.getQueryLocator is a method in Salesforce's Apex that is used to retrieve records from the database for batch processing. It is typically used in the start method of a Batchable class to define the scope of records that the batch job will process.
It executes a SOQL query and returns a Database.QueryLocator object. The returned QueryLocator can efficiently handle large datasets by fetching records in chunks (batches), which are passed to the execute method of the batch class.
Large Record Sets: Database.getQueryLocator can handle up to 50 million records in a single query. This is much more than a standard SOQL query, which can retrieve only 50,000 records.
Syntax :
public static Database.QueryLocator getQueryLocator(String query)
Database.BacthableContext:
The Database.BatchableContext interface in Salesforce is used in Batch Apex to provide context about the execution of the batch job. It acts as a reference to the current state of the batch job and is passed as an argument to the start, execute and finish methods of a batch class.
Key Features of BatchableContext:
Job Identification:
- It provides the job ID of the batch job that is running. You can use this ID to track or monitor the job in the Salesforce setup.
Code:
public class OpportunityBatchPractice implements Database.Batchable<SOBJECT>, Database.Stateful {
public Integer recordCount = 0;
public Database.QueryLocator start(Database.BatchableContext bc) {
String query = 'SELECT Id, LeadSource FROM Opportunity';
return Database.getQueryLocator(query);
}
public void execute(Database.BatchableContext bc, List<Opportunity> opportunityList) {
if (!opportunityList.isEmpty()) {
for (Opportunity opportunity : opportunityList) {
opportunity.LeadSource = 'Web';
opportunity.Amount = 10;
}
update opportunityList;
recordCount += opportunityList.size();
}
}
public void finish(Database.BatchableContext bc) {
System.debug('Total Record Process ' + recordCount);
}
}
Scheduled Apex
In Salesforce, Scheduled Apex allows you to schedule the execution of Apex classes to run at a specific time. This is useful for automating tasks like batch processing, data cleanup, or sending reminders.
Code:
public class MyScheduledClass implements Schedulable {
public void execute(SchedulableContext sc) {
// Your logic here
System.debug('Scheduled Apex executed at ' + System.now());
}
}
Invoke Scheduleable
SchedulePractice obj = new SchedulePractice();
System.schedule('Daoly Clean up', '0 0 0 * * ?', obj);
Scheduling the class
From Setup:
Navigate to Setup > Apex Classes.
Click Schedule Apex.
Enter a job name.
Select the Apex class to schedule.
Define the schedule (frequency, start date, time, etc.).
From Developer Console or Code (Using CRON Expression):
String schedule = '0 0 12 * * ?'; // Runs daily at 12 PM System.schedule('Daily Apex Job', schedule, new MyScheduledClass());
- CRON Expression Syntax
Seconds Minutes Hours Day_of_month Month Day_of_week Optional_year
View Scheduled Jobs:
- Go to Setup > Scheduled Jobs to see and manage scheduled jobs.
CRON Expression Format:
Seconds Minutes Hours Day_of_month Month Day_of_week Optional_year
Meaning of * in Different Positions:
Seconds (
*): Represents every second in a minute (0–59).- Example:
* * * * * ?— Executes every second.
- Example:
Minutes (
*): Represents every minute in an hour (0–59).- Example:
0 * * * * ?— Executes at the start of every minute.
- Example:
Hours (
*): Represents every hour in a day (0–23).- Example:
0 0 * * * ?— Executes at the start of every hour.
- Example:
Day_of_month (
*): Represents every day in the month (1–31).- Example:
0 0 12 * * ?— Executes daily at 12:00 PM.
- Example:
Month (
*): Represents every month (1–12 or JAN–DEC).- Example:
0 0 12 * * ?— Executes every month on the specified schedule.
- Example:
Day_of_week (
*): Represents every day of the week (1–7, where 1 = Sunday or SUN–SAT).- Example:
0 0 12 * * *— Executes every day of the week at 12:00 PM.
- Example:
Optional_year (
*): Represents every year (optional, typically ignored in Salesforce CRON expressions).- Example:
0 0 12 * * ? *— Executes every year at 12:00 PM.
- Example:
Example of * in Use:
To schedule a job that runs every hour on the hour, the CRON expression would be:
0 0 * * * ?
0: Start at the 0th second.0: Start at the 0th minute.*: Run every hour.*: Run every day of the month.*: Run every month.?: Any day of the week.
System.Schedule() method
System.schedule() is a method in Apex that is used to schedule an Apex class to execute at a future time or on a recurring schedule. It allows you to define a job in code using a CRON expression to specify when the job should run.
Method Signature:
public static String schedule(String jobName, String cronExpression, Schedulable instance)
ScheduableContext interface
SchedulableContext is an interface in Salesforce used in Scheduled Apex. It provides context and information about the scheduled job when the execute() method of a class implementing the Schedulable interface is called.
Key Features of SchedulableContext
- Provides Job ID:
It includes a method to retrieve the unique ID of the scheduled job.