Friday, August 7, 2015

Resolution for Too many future calls limit in Apex

In Sales force we do have many limits one among them is @future calls(asynchronous). Salesforce has a limit of 50 future calls for a single transaction.

Salesforce has introducted Queueable interface supersede the old @future annotation in Apex. now you can chain a job to another job an unlimited number of times.

Trigger
trigger SendAccount on Account(after insert)
{ 
 for(Account a : Trigger.new)
  {
 SendAccountUsingRESTAPI.callcreateAcc(a.Name, a.Id);
  }
}
SendAccountUsingRESTAPI Apex Class
public class SendAccountUsingRESTAPI {
  @future(callout=true)
   public static void callcreateAcc (String accName, String accId)
   {
  System.debug('Created Account Name:'+accName);
  System.debug('Created Account Id:'+accId);
   }
}

I tried to call future method 50 times below is code. Execute the code in developer console or on the Apex Execute on Workebench

List<Account> lstAccount=new List<Account>();
for(Integer i=0;i<51;i++){
 Account acc=new Account();
 acc.Name= 'Test Sample'+i;
 lstAccount.add(acc);
}
insert lstAccount;
I modifed the trigger and created a new class AccountQueuebleJob which implements Queueable. I ran the same code above eeverything when fine.
trigger SendAccount on Account(after insert)
{
  List<Account> lstAccount =new List<Account>();
  for(Integer i=0;i<Trigger.new.size();i++){
      if(i<50){
          SendAccountUsingRESTAPI.callcreateAcc(Trigger.new[i].Name, Trigger.new[i].Id);
      }else{
          lstAccount.add(Trigger.new[i]);
      }
  }
  
  if(!lstAccount.isEmpty()){
      ID jobID = System.enqueueJob(new AccountQueuebleJob(lstAccount));
  }
}
AccountQueuebleJob Class
public class AccountQueuebleJob implements Queueable, Database.AllowsCallouts {

    private List<Account> lstAccount;
    
    public AccountQueuebleJob(List<Account> lsacc){
        this.lstAccount = lsacc;
    }

    public void execute(QueueableContext context) {
        if(!lstAccount.isEmpty()){
            for(Account a:lstAccount){
                SendAccountUsingRESTAPI.callcreateAcc(a.Name, a.Id);
            }
        }
        
    }
}

7 comments:

  1. Hi Suresh,
    is this solution working for for you ?. I tried same solution but I am facing too many future limits because limit is 50 per transaction. Here is my sample code.


    public class TempQueueableTest implements Queueable {
    // implements Queueable

    public void execute(QueueableContext context) {
    for(integer i = 0; i <= 60; i++){
    calcCommunityRollups(commID);
    }
    }

    @future
    public static void calcCommunityRollups(id communityID) {
    System.debug('This is for testing');
    }

    }

    ReplyDelete
  2. Thank You Blogger for such a Beautiful Blog.Your Blog Design Perfect Report and Level Too Thanks By Research Panel.
    Free Trial

    ReplyDelete
  3. Hi, I implmented this solution but I face the same limitation with Queue : too many queueable jobs added to the queue : 51.

    ReplyDelete
  4. It is not working

    ReplyDelete
  5. This is great, although I realised that you can't call a future method from a Queueable class, and so had to remove the @Future(callout=true) from my callout method. I then experienced a further limit "Too many callouts: 101", and so I called the Queueable calls multiple times, each time with list of 100 records, and this works great. Thanks again and all good wishes. Paul

    ReplyDelete