0

I am trying to write a batch class which retries to do the callout 3 times if a record failed to send to a web service.

global class LeadExporterFailedRetry implements Database.Batchable<Sobject>,Database.allowscallouts{

global  String jobName;
global Boolean bAutoSchedule = false;
global Integer DEFAULT_RESTART_TIME = 1;
global Integer restartTimeInMins = DEFAULT_RESTART_TIME;
global set<Id> leadIds = new set<Id>();
global set<Id> leadInfoIds = new set<Id>();
global Map<Id,Lead> IdToLeadMap = new Map<Id,Lead>();//Map to hold the leads
global Map<Id,LeadInfo__c> IdToLeadInfoMap = new Map<Id,LeadInfo__c>();//Map to hold the leadinfos

/*
    @Param: Jobname -
    @Param: iRestartTimeInMins - time in minutes after which job should restart itself.
*/
/*
public LeadExporterFailedRetry(String theJobName, Integer iRestartTimeInMins) {

    jobName = theJobName;       
    if(iRestartTimeInMins > 0){
        restartTimeInMins = iRestartTimeInMins;
        bAutoSchedule = true;
    }
}
*/
global database.QueryLocator start(database.BatchableContext bc){

    return Database.getQueryLocator('select Contact__c,Lead__c,Lead_Exporter__c,LeadInfo__c,Response_Code__c,Result__c,Sent_Time__c,Retry_Count__c,Zip_Code__c from Lead_Export_Result__c where Result__c=\'Failed\' and Retry_Count__c !=3 and id =\'a0p4B000000MHEH\'');
}
global void execute(database.BatchableContext bc,list<Lead_Export_Result__c> scope){

   list<Lead_Export_Result__c> LEResults = scope;

    For(Lead_Export_Result__c LeTemp : scope){

        if(LeTemp.Lead__c != null)
            leadIds.add(LeTemp.Lead__c);   

        if(LeTemp.LeadInfo__c != null)
            leadInfoIds.add(LeTemp.LeadInfo__c);
    }

    list<lead> LeadList = [select id,Do_Not_export__c,email,LastName,FirstName,Primary_Phone__c from Lead where id in :leadIds];

    list<LeadInfo__c> LeadInfoList = [select id,Message__c,Lead_Address__c,Lead_City__c,Lead_State__c,Lead_Zip_Code__c from LeadInfo__c where id in :leadInfoIds];

    for(Lead leadTemp: LeadList){
        IdToLeadMap.put(leadTemp.id, leadTemp);
    }

    for(LeadInfo__c leadInfoTemp: LeadInfoList){
        IdToLeadInfoMap.put(leadInfoTemp.id, leadInfoTemp);
    }

    for(Lead_Export_Result__c LeVar: LEResults){

        Lead leadP = IdToLeadMap.get(LeVar.Lead__c);
        LeadInfo__c LeadinfoP = IdToLeadInfoMap.get(LeVar.LeadInfo__c);
        String payload = MovotoUtilities.buildExportRealTimePayload(LeVar.Lead_Exporter__c, leadP, LeadinfoP); 
        system.debug('lead id:'+leadP.id);
        while(LeVar.Result__c != 'Success' || (LeVar.Retry_Count__c != 1)){
            system.debug('inside retry');
            Lead_Export_Result__c Expores =  SendOutboundMessage.LeadExporter( LeadinfoP.Id+'',  '',  leadP.Id+'', LeVar.Lead_Exporter__c+'', false, UserInfo.getsessionId(),UserInfo.getuserId(),  payload);
            if(Expores.Result__c == 'Failed'){
                if(LeVar.Retry_Count__c == null)
                        LeVar.Retry_Count__c = 0;
                LeVar.Retry_Count__c = LeVar.Retry_Count__c + 1;
            }
            else  
                LeVar.Result__c = 'Success';             
        }
        if(LeVar.Result__c == 'Failed'){
            leadP.Do_Not_export__c = true;
            leadP.status = 'Lead Export Failure';
        }
    } 

    if(LEResults !=null && !LEResults.isEmpty()){

        update LEResults;
    }
}

 global void finish(database.BatchableContext bc){

 }
}

I am getting the error that "You have uncommitted work pending. Please commit or rollback before calling out". need a help on this

2

The message would seem to indicate that you are attempting to do DML operations before callouts. In your code I only see the one DML statement and it's at the end of the execute method. So I must conclude that one of your other methods such as MovotoUtilities.buildExportRealTimePayload or SendOutboundMessage.LeadExporter contains DML statements.

So you'll want to find a way to refactor that avoids doing any DML until all callouts are done. It could also do some DML asynchronously (i.e. via Queueable) but there's a cap on how many of those a batch can call, so you'd need to bulkify the method you're calling.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.