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 Answer 1

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
}
1
  • 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
    Commented May 29, 2019 at 19:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .