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
Shalini RShalini R 

Future callout issue - You have uncommitted work pending. Please commit or rollback before calling out

Hi, 

I got the above error when i send sms to above 50 phone numbers. i have query some records then calling future callout method.
Please share your comments if you face this type of issue.
 
sfdcMonkey.comsfdcMonkey.com
hi shallni, please refer below link for your solution :
https://help.salesforce.com/articleView?id=000003701&type=1
Hopes it helps you, let us know if it helps you
Thanks
Shalini RShalini R
Hi piyush_soni,
Thanks for your reply.
I have to used two methods. One method for to select some records then call to another method which is @future callout method for sending message. So, when run this class it will show future call out error - 51.
Example - I have to select 150 members of records from query, then call future method for sms.
Please let me know if you know how to solve this error.
sfdcMonkey.comsfdcMonkey.com
can you please share your all apex code snippet here
thanks
Shalini RShalini R
If i select below 50 records from query then send sms wokring properly, otherwise display error message.

Coding -

    String messageBody='test';
    String phoneNum;
    public void test(){
    accountList=new List<account>([select id,name,type,phone from account]);
        if(accountList.size()>0){
            for(integer i=0;i<accountList.size();i++){ 
                    phoneNum=accResult.get(i).phone;
                    smssend(phoneNum,messageBody);
            } 
                    
        }
  
    } 
    @future(callout=true)
    public static void smssend(String phoneNum, String messageBody)
    {  
    ... sms coding ....
    }
sfdcMonkey.comsfdcMonkey.com
hey :

Below point you need to consider for all Future call

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

so don't call your future method inside for loop ... do someting like below :

 
 
 public void test(){
    accountList = new List<account>([select id,name,type,phone from account]);
      set<string> lstPhoneNumber = new set<String>();
        if(accountList.size()>0){
            for(integer i=0;i<accountList.size();i++){
                    lstPhoneNumber.add(accResult.get(i).phone);
                    
            }
       // call future method outside the for loop              
         smssend(lstPhoneNumber,messageBody);
        }
    }
   
    @future(callout=true)
    public static void smssend(set<string> phoneNum, String messageBody)
    {  
      ... sms coding ....
    }

i hope it helps you.
      Let me inform if it helps you and kindly mark it best answer if it helps you so it make proper solution for others [ Forums Best Practice (https://developer.salesforce.com/forums/ForumsMain?id=9060G000000MVrtQAG" target="_blank) ]
 thanks
http://sfdcmonkey.com
v varaprasadv varaprasad
Hi Shalini,

Please use Queueable  Apex to avoid error increase limits of records.

Instead of implementing future method you can pass same values to Queueable class.
 
public class UpdateParentAccount implements Queueable {
    
    set<string> phoneNum;
	String messageBody;
    
    public UpdateParentAccount(set<string> phoneNum, String messageBody) {
        this.phoneNum= phoneNum;
        this.messageBody=messageBody;
    }

    public void execute(QueueableContext context) {
        //Here Send mail
    }
    
}
Then call class in your class:
UpdateParentAccount updater = new UpdateParentAccount(accounts, parentId);
            
        System.enqueueJob(updater);

More Info:

https://trailhead.salesforce.com/en/modules/asynchronous_apex/units/async_apex_queueable


i hope it helps

Thanks
Varaprasad






 
Shalini RShalini R
Hi ,

Thank you to all.
I have used map to pass phone number with other details also. Its working fine. But it only allowed 100 phone numbers( 100 future callout only allowed). Then i tried with the below code by using Queueable interface to overcome this. I got job id with status as completed but message should not send to mobile numbers.
Please share me if you know the reason.

Main Class  -

public class sample{
Map<String,String> newmp=newm Map<String,String>();

public void samplemet(){
      newmap.put(x,y);
      //call Queueable interface
      queclass q=new queclass (newmap);
      ID jobID=System.enqueueJob(q);
      system.debug('jobid'+jobID);
}

}

Queable inteface -

public class queclass implements Queueable{
Map<String,String> a1=new Map<String,String>();
public queclass (Map<String,String> mp){
        this.a1= mp;
   }    
      
public void execute(QueueableContext context){
       ---  sms coding ---
    }
}