function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
NehaDabas16NehaDabas16 

Future methods vs Queueable Apex

Both future methods and queueable apex are types of asynchronous apex. One of the differences between the two is that, future methods can only accept primitive data types parameters and not sObjects, and the reason for that is also justified that object state might change between when the method is called and when it is actually executed.
However we can pass sObjects to Queueable Apex. 

Please help me understand how is sObject state kept in sync in case of Queueable Apex.
Raj VakatiRaj Vakati
Refer this link 

https://developer.salesforce.com/forums/?id=906F0000000kK6VIAU
https://blogs.perficient.com/2016/03/03/queueable-vs-future/
https://trailhead.salesforce.com/content/learn/modules/asynchronous_apex/async_apex_queueable


You can pass Sobject like below ..using Constructor  .. code is below  at the end and you can see in the above trailhead link



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
    }
}

NOTE :-

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
    }

}


You can pass Sobject like below ..using Constructor 
The following code takes a collection of Account records, sets the parentId for each record, and then updates the records in the database.
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;
    }
    
}

To add this class as a job on the queue, execute the following code:
// 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);



 
NehaDabas16NehaDabas16
Hi Raj,

I have been through these articles. What I am trying to ask is, how are sObjects allowed in Queueable apex, are they passed by reference? 

As "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" this reason should apply to all the async methods. How is it made sure, that sObject doesnot change between when Queueable apex is called and when it is actually executed?

I hope I could make my point more clear this time.