+ Start a Discussion
farah sheriffarah sherif 

I dont understand  Queueable apex and the difference between it and @future can anyone explain?

Raj VakatiRaj Vakati
@future

A future method runs asynchronously. And its governor limits are higher:
 
Long-running operations (callouts to external web service)
Separating mixed DML operations (i.e. inserting a user with a non-role must be done in a separate thread from DML operations on other sObjects)
 

future anotation
Must be static and return void
Specify (callout=true) to allow callouts


Parameters passed in can be only of Primitive type
Cannot chain @future method
Cannot get the job ID


Queueable Interface methods and Future methods are Asynchronous Apex Processes that add jobs to the job queue and each job runs when system resources become available, so it doesn’t delay the execution of the main Apex logic. They also share a benefit of having some higher governor limits than synchronous Apex, such as heap size limits (12 MB),  number of SOQL queries issued (200) and Maximum CPU time on the Salesforce servers (60k ms). But the Queueable interface methods are a step up from the future methods because they also come with these additional benefits (according to Salesforce release notes):

To define a future method, simply annotate it with the future annotation, as follows:-

 
global class FutureClass
{
    @future
    public static void myFutureMethod()
    {   
         // Perform some operations
    }
}


1) Methods with the future annotation must be static methods
2) can only return a void type
3) The specified parameters must be primitive data types, arrays of primitive data types, or collections of primitive data types
4) Methods with the future annotation cannot take sObjects or objects as arguments.
5) You can invoke future methods the same way you invoke any other method. However, a future method can’t invoke another future method
6) No more than 50 method calls per Apex invocation
7) Asynchronous calls, such as @future or executeBatch, called in a startTest, stopTest block, do not count against your limits for the number of queued jobs
8) The maximum number of future method invocations per a 24-hour period is 250,000 or the number of user licenses in your organization multiplied by 200, whichever is greater
9) To test methods defined with the future annotation, call the class containing the method in a startTest(), stopTest() code block. All asynchronous calls made after the startTest method are collected by the system. When stopTest is executed, all asynchronous processes are run synchronously


IMP:-
The reason why sObjects can’t be passed as arguments to future methods is because the sObject might change between the time you call the method and the time it executes. In this case, the future method will get the old sObject values and might overwrite them.  To work with sObjects that already exist in the database, pass the sObject ID instead (or collection of IDs) and use the ID to perform a query for the most up-to-date record. The following example shows how to do so with a list of IDs


Example of a future method that makes a callout to an external service. Notice that the annotation takes an extra parameter (callout=true) to indicate that callouts are allowed
 

 
global class FutureMethodExample
{
    @future(callout=true)
    public static void getStockQuotes(String acctName)
    {   
         // Perform a callout to an external service
    }

}



Queueable Interface

This interface enables you to add jobs to the queue and monitor them which is an enhanced way of running your asynchronous Apex code compared to using future methods.
Like @future, a benefit of using the Queueable interface is that some governor limits are higher than synchronous Apex (see the table above).

 
When to use it comparing with @future:
Chaining jobs
Asynchronous monitoring (it gets job ID)
Using non-primitive types
 

Getting an ID for your job: When you submit your job by invoking the System.enqueueJob method, the method returns the ID of the new job. This ID corresponds to 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 by starting a second job from a running job. Chaining jobs is useful if you need to do some processing that depends on another process to have run first.


Below is an example of how to implement the Queueable interface.
 
 
public class AsyncExecutionExample implements Queueable {
     public void execute(QueueableContext context) {
          Account a = new Account(Name='Acme',Phone='(415) 555-1212');
          insert a; 
     }
}


You can add the class to a job queue by calling this method.


ID jobID = System.enqueueJob(new AsyncExecutionExample());

If you have a second class that also implements the Queueable interface and you want it to run after the class above is done, you can chain them together like this:
 
public class AsyncExecutionExample implements Queueable {
     public void execute(QueueableContext context) {
          Account a = new Account(Name='Acme',Phone='(415) 555-1212');
          insert a; 

         // Chain this job to next job by submitting the next job
         System.enqueueJob(new SecondJob());
     }
}

 
farah sheriffarah sherif
what does the below code do?


public class UpdateParentAccount implements Queueable {
private List<Account> accounts;
private ID parent;
public UpdateParentAccount(List<Account> records, ID id) {
this.accounts = records; this.parent = id;
}
public void execute(QueueableContext context) {
for (Account account : accounts)
{
account.parentId = parent;
// perform other processing or callout
}
update accounts;
}
}
Raj VakatiRaj Vakati
It's a queueable class and in the constructor you see two parameters which is List<Account> records and one id of the parent record to be updated  .. I you execut the below code from developer console you can able to see the all list of accounts are updated with parent account

 
// find all accounts in ‘NY’
List<Account> accounts = [select id from account where billingstate = ‘NY’];
// find a specific parent account for all records
Id parentId = [select id from account where name = 'ACME Corp'][0].Id;
// instantiate a new instance of the Queueable class
UpdateParentAccount updateJob = new UpdateParentAccount(accounts, parentId);
// enqueue the job for processing
ID jobID = System.enqueueJob(updateJob);