0

Is it possible to create a batch class that makes x calls to take n records at a time and run the dml of these records? For example. I call the service. I read the first 200 records and do dml, then call the service again, read the other 200 records and run the dml.

global class BatchCallout implements Database.Batchable<sObject>, Database.AllowsCallouts, Database.Stateful {

Integer successRecords = 0;
Integer errorRecords = 0;
Integer offset = 0;
Integer maxOffset;
Boolean stopCallout = false;
String endpoint;

global BatchCallout(Integer maxOff){
    maxOffset = maxOff;
}

global Database.QueryLocator start(Database.BatchableContext BC) {

}

global void execute(Database.BatchableContext BC, List<SObject> scope) {
    if (offset <= maxOffset){
        //make callout
        Http h = new Http();
        HttpRequest req = new HttpRequest(); 
        req.setMethod('GET');                                                                                  
        req.setEndpoint(endpoint+'?offset='+offset); 
        HttpResponse res = h.send(req);
        if (res.getStatus() == 200){
            Map<String,Object> results = (Map<String,Object>)JSON.deserializeUntyped(res.getBody());

            //increment offset
            offset++;

            //make DML
            insert records
        } else {
            //make callout with same offset
            //reinvoke execute method ??? 
        }
    }
}   

global void finish(Database.BatchableContext BC) {
    System.debug('Records success: '+successRecords);
    System.debug('Records error: '+errorRecords);

} }

1

Your code will be fine if each execute call does callout then DML:

public void execute(Database.BatchableContext context, List<SObject> records)
{
    // perform callout

    // perform DML
}

Each run through the method executes in a distinct transaction. However, if you try to further chunk the scope records, you need to make sure you do all the callouts before any of the DML.

public void execute(Database.BatchableContext context, List<SObject> records)
{
    // perform callout 1
    // perform callout 2
    // perform callout 3
    // perform callout 4
    // perform callout 5

    // perform DML
}
|improve this answer|||||
  • I added the code to my question. In my case, what should the start method return? The List <SObject> scope parameter in the execute method is also unused. I don't know if the problem is clear. The volume of data to be imported is around 40k and the web service returns 1000 records at a time. The offset is used to get next records. – maidenfp May 29 '19 at 19:41

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.