+ Start a Discussion
Lakshmi SLakshmi S 

Future method Example

Hi All,

Q). What is a future method ? When we are going to use Future methods? Example program for Future method and Schedulable class for Future method?

Give me reply anyone.....
Best Answer chosen by Lakshmi S
NagendraNagendra (Salesforce Developers) 
Hi Lakshmi Narasimha,

What is Future Method:

A future method runs in the background, asynchronously. You can call a future method for executing long-running operations, such as callouts to external Web services or any operation you'd like to run in its own thread, on its own time.

When to use Future Method:

If you want to make the execution of the apex program to run asynchronously then we make use of future method.When you specify
future , the method executes when Salesforce has available resources. For example, you can use the future annotation when making an asynchronous Web service callout to an external service.

Apex class with Future Method:
public class AccountProcessor 
{
  @future
  public static void countContacts(Set<id> setId) 
  {
      List<Account> lstAccount = [select id,Number_of_Contacts__c , (select id from contacts ) from account where id in :setId ];
      for( Account acc : lstAccount )
      {
          List<Contact> lstCont = acc.contacts ;
          
          acc.Number_of_Contacts__c = lstCont.size();
      }
      update lstAccount;
  }
}

Test class for the above:
@IsTest
public class AccountProcessorTest {
    public static testmethod void TestAccountProcessorTest() 
    {
        Account a = new Account();
        a.Name = 'Test Account';
        Insert a;

        Contact cont = New Contact();
        cont.FirstName ='Bob';
        cont.LastName ='Masters';
        cont.AccountId = a.Id;
        Insert cont;
        
        set<Id> setAccId = new Set<ID>();
        setAccId.add(a.id);
 
        Test.startTest();
            AccountProcessor.countContacts(setAccId);
        Test.stopTest();
        
        Account ACC = [select Number_of_Contacts__c from Account where id = :a.id LIMIT 1];
        System.assertEquals ( Integer.valueOf(ACC.Number_of_Contacts__c) ,1);
  }
  
}

Instead of a Schedulable class, try using a batch class. batch classes can be scheduled using the UI, and can call @future methods.
global class ScheduledDispatcher Implements Schedulable{

    public Interface IScheduleDispached{
        void execute(SchedulableContext sc);
    }

    global void execute(SchedulableContext sc){
        Type targetType = Type.forName('{HANDLERNAME');
        if(targetType != null){
            IScheduleDispached obj = (IScheduleDispached)targetType.newInstance();
            obj.execute(sc);
        }
    }


}

public class {HANDLERNAME} implements ScheduledDispatcher.IScheduleDispached {

  public void execute(SchedulableContext sc)
    {

        //Call your Future Method Here

    } 

}
For more information refer to the below link.
http://amitsalesforce.blogspot.sg/2015/02/future-methods-in-salesforce.html

Kindly mark my solution as the best answer if it helps you.

Best Regards,
Nagendra.P

All Answers

NagendraNagendra (Salesforce Developers) 
Hi Lakshmi Narasimha,

What is Future Method:

A future method runs in the background, asynchronously. You can call a future method for executing long-running operations, such as callouts to external Web services or any operation you'd like to run in its own thread, on its own time.

When to use Future Method:

If you want to make the execution of the apex program to run asynchronously then we make use of future method.When you specify
future , the method executes when Salesforce has available resources. For example, you can use the future annotation when making an asynchronous Web service callout to an external service.

Apex class with Future Method:
public class AccountProcessor 
{
  @future
  public static void countContacts(Set<id> setId) 
  {
      List<Account> lstAccount = [select id,Number_of_Contacts__c , (select id from contacts ) from account where id in :setId ];
      for( Account acc : lstAccount )
      {
          List<Contact> lstCont = acc.contacts ;
          
          acc.Number_of_Contacts__c = lstCont.size();
      }
      update lstAccount;
  }
}

Test class for the above:
@IsTest
public class AccountProcessorTest {
    public static testmethod void TestAccountProcessorTest() 
    {
        Account a = new Account();
        a.Name = 'Test Account';
        Insert a;

        Contact cont = New Contact();
        cont.FirstName ='Bob';
        cont.LastName ='Masters';
        cont.AccountId = a.Id;
        Insert cont;
        
        set<Id> setAccId = new Set<ID>();
        setAccId.add(a.id);
 
        Test.startTest();
            AccountProcessor.countContacts(setAccId);
        Test.stopTest();
        
        Account ACC = [select Number_of_Contacts__c from Account where id = :a.id LIMIT 1];
        System.assertEquals ( Integer.valueOf(ACC.Number_of_Contacts__c) ,1);
  }
  
}

Instead of a Schedulable class, try using a batch class. batch classes can be scheduled using the UI, and can call @future methods.
global class ScheduledDispatcher Implements Schedulable{

    public Interface IScheduleDispached{
        void execute(SchedulableContext sc);
    }

    global void execute(SchedulableContext sc){
        Type targetType = Type.forName('{HANDLERNAME');
        if(targetType != null){
            IScheduleDispached obj = (IScheduleDispached)targetType.newInstance();
            obj.execute(sc);
        }
    }


}

public class {HANDLERNAME} implements ScheduledDispatcher.IScheduleDispached {

  public void execute(SchedulableContext sc)
    {

        //Call your Future Method Here

    } 

}
For more information refer to the below link.
http://amitsalesforce.blogspot.sg/2015/02/future-methods-in-salesforce.html

Kindly mark my solution as the best answer if it helps you.

Best Regards,
Nagendra.P
This was selected as the best answer
Amit Chaudhary 8Amit Chaudhary 8
I will recomment you to start learning from trailhead
1 ) https://developer.salesforce.com/trailhead/module/asynchronous_apex

Please check below post for Future mothod
1) http://amitsalesforce.blogspot.com/2015/02/future-methods-in-salesforce.html

A future method runs in the background, asynchronously. You can call a future method for executing long-running operations, such as callouts to external Web services or any operation you’d like to run in its own thread, on its own time. You can also make use of future methods to isolate DML operations on different sObject types to prevent the mixed DML error. Each future method is queued and executes when system resources become available. That way, the execution of your code doesn’t have to wait for the completion of a long-running operation. A benefit of using future methods is that some governor limits are higher, such as SOQL query limits and heap size limits

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

Let us know if this will help you
 
Rakesh51Rakesh51
The @future annotation is typically used in one of two ways:

1) Create a better user experience - Let's say you have a process that whenever an Opportunity is created a number of calculations are made on a custom object. However, since these calculations don't affect what the user is currently doing, why make them wait as these calculations are made? Apex methods marked with the @future annotation are executed asynchronously when Salesforce has available resources. A better solution is to create the Opportunity and call your calculations asynchronously so that the user does not have to wait for them to finish processing.

2) Calls to external web services - As Force.com applications have taken more of centralized role in the enterprise application architecture, there is an evolving need to keep external systems in sync. Suppose you have a requirement (not uncommon) that each time you update a contact you have to call an external webservice to update the contact in SAP, Siebel, etc. Since callouts are prohibited in triggers, you need to call an Apex class with a @future method that is marked as (callout=true).

The @future annotation is a great tool but with great power comes great responsibility. Here are some things you need to keep in the back of your mind when using them:

1) Depending on the number of licenses you have you may bump into some org-wide limits as Salesforce imposes a limit on the number of future method invocations. You can only have 200 method calls per full Salesforce user license or Force.com App Subscription user license, per 24 hours. This is understandable (i.e., limits != evil) but what if you are doing data loading/cleanup or have installed a managed package that puts you over your limit, you simply have to wait for you invocations to reset and somehow reprocess those items that failed.

2) No more than 10 method calls per Apex invocation. This one is understandable as well but I've seen a number of projects where we've had to implement some other type of system (polling for instance) because the limitation makes this approach technically impossible. The example is, suppose you have a trigger that updates 11 contact records (or 200!) and needs to make a callout for each record. You are screwed unless you have the luxury of being able to rewrite your external webservice to accept a collection of records.

3) You cannot call a method annotated with @future from a method that also has the @future annotation. We've run into this a number of times as the class hierarchy grows in larger projects. You want to reuse an existing class but what happens if it already calls a @future method? Or what happens if an managed package contains a @future method?

4) The parameters for a @future method must be primitive data types, arrays of primitive data types, or collections of primitive data types. Not a big deal as you can typically pass the IDs of the affected records and query for them. But doesn't that seem like a waste of resources if the Apex that calls the @future method already holds these records? It would be great if you could pass a collection of sObject or Apex objects.

5) It's difficult to orchestrate processes with @future annotations because these methods do not necessarily execute in the same order they are called.
 
Arun Garg 9Arun Garg 9
Best Article about Future Method and solution to prevent Mixed DML Error using Future Mehod. (http://www.salesforceadda.com/2017/08/future-method-and-prevent-mixed-dml.html)
farukh sk hdfarukh sk hd
Future method are annoted with @future annotation which indicates that the method will run
asynchronously(i.e in future when resources are available to it).Normal method runs as soon as 
it executes in same thread but future method runs in different thread.Future method always require id's as parameter,Objects are not allowed as there is a possibility that when future method runs data might have changed which can lead to processing on wrong data.

For more information...Visit,

https://www.sfdc-lightning.com/2018/10/future-methods-in-salesforce.html