Wednesday, June 28, 2017

@future Annotation in salesforce :

What is the use of “@future” annotation?

Future annotations are used to identify and execute methods asynchronously. If the method is annotated with “@future”, then it will be executed only when Salesforce has the available resources.
For example, you can use it while making an asynchronous web service callout to an external service. Whereas without using the annotation, the web service callout is made from the same thread that is executing the Apex code, and no additional processing will occur until that callout is complete (synchronous processing).


What are @Featuremethod Considerations?


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. Methods with the future annotation cannot take sObjects or objects as arguments.


  • Specify (callout=true) to allow callouts in a future method. 
  • Specify (callout=false) to prevent a method from making callouts.


@future (callout=true)
  public static void doCalloutFromFuture() {
   //Add code to perform callout
}


  • Remember that any method using the future annotation requires special consideration because the method does not necessarily execute in the same order it is called.
  • Methods with the future annotation cannot be used in Visualforce controllers in either getMethodName or setMethodName methods, nor in the constructor.
  • You cannot call a method annotated with future from a method that also has the future annotation. Nor can you call a trigger from an annotated method that calls another annotated method.
  • The getContent and getContentAsPDFPageReference methods cannot be used in methods with the future annotation.
Example:
trigger FutureTrigger on Account (after insert, after update) {
  for(Account a: Trigger.new){
    // Invoke the @future method for each Account()
    // This is inefficient and will easily exceed the governor limit of
    // at most 10 @future invocation per Apex transaction
    futureTriggerClass.processAccount(a.id);
      //it should be pass the single record at once
     //System.LimitException: Too many future calls: 51
   } /* 
   // Write like below line should bypass the above exception
    futureTriggerClass.processAccount(trigger.newmap.keyset());
    */
}
------------
global class futureTriggerClass {
  
 //For multiple records at one time
 // public static void processAccount(set<Id> accountId) {
 // For single record
 private static final Boolean isEnabled = isEnabled();
    
    @future
  public static void processAccount(Id accountId) {
       if (isEnabled) { 
       List<Contact> contacts = [select id, salutation, firstname, lastname, email
                from Contact where accountId = :accountId];
      list<contact> lstcon = new list<contact>();
         for(Contact c: contacts){
        System.debug('Contact Id[' + c.Id + '], FirstName[' + c.firstname + '], LastName[' + c.lastname +']');
                      c.Description=c.salutation + ' ' + c.firstName + ' ' + c.lastname;
             // c.status__c.adderror('error');
             c.status__c = 'active';
             system.debug('==========>'+c.status__c);
             lstcon.add(c);
        }
        update lstcon;       
  }
     }
     public static boolean isEnabled () {
        //enable the trigger for test classes
        if(Test.isrunningTest()) {
            return true; 
        } else {
            System.debug('checking user profile to determine if triggers should be run');
            // <<006>> return jl_runtriggers__c.getInstance(UserInfo.getProfileId()).Run_Triggers__c;
            return jl_runtriggers__c.getInstance().Run_Triggers__c; // <<006>>
        }
    }  
}



No comments:

Post a Comment