1

I am processing hundreds of thousands of call records that must be assigned to their respective telephone lines based on the phone number. I wanted to retrieve a list of Phone Line records and then create multiple batch jobs to find all related telephone call records.

    public void GetLines(){

            List<Lines__c> lines = [Select id, phone_number__c from lines__c ORDER BY Line_Status__c ASC];

            for(Lines__c l: lines){
                       ExecuteBatchUpdate(l.id, l.phone_number__c );         
            }  
        }

    public void ExecuteBatchUpdate(Id lineid, String phone){
    ..
    If(Test.isRunningTest()){
                Id batchInstanceId = Database.executeBatch(new BatchUpdateCallRecordsAssingLine(q, Lineid), 20); 
                System.abortJob(batchInstanceId);
            }else{
                    Database.executeBatch(new BatchUpdateCallRecordsAssingLine(q, Lineid));
            }
    ..
    }

 global void execute(Database.BatchableContext bc, List<Detailed_Call_Data__c> scope){

    List <Detailed_Call_Data__c> callsData = new List<Detailed_Call_Data__c>();

    for (Detailed_Call_Data__c callrec : scope) {
        Detailed_Call_Data__c rectoupdate = new Detailed_Call_Data__c();
        rectoupdate.id = callrec.id;
        rectoupdate.Line__c = lineId; 

        callsData.add(rectoupdate);
    }
    update callsData;
} 

Unfortunately, I get System.LimitException: Too many DML statements: 151.

Is it possible to call Database.executeBatch from a loop? If not, what is the right way do deal with this scenario?

9
  • have each batch finish() invoke the next batch
    – cropredy
    Oct 31, 2019 at 17:27
  • 1
    What are the batches doing? Calling a batch with a single record input is not an ideal use case most of the time.
    – David Reed
    Oct 31, 2019 at 17:32
  • the batch picks up thousands of Phone Call records and adds a relationship with a matching line based on the phone number. there are 12K Lines and thousands of call records.
    – wmin
    Oct 31, 2019 at 17:41
  • @cropredy could you pls elaborate?
    – wmin
    Oct 31, 2019 at 18:12
  • i'm with David - why not execute a single batch where the start method does the query on Lines__c?
    – cropredy
    Oct 31, 2019 at 18:22

1 Answer 1

0

I think you may be shortchanging yourself on the power of Batch Apex.

My understanding is this. You've got some records in Lines__c, at high volume (12K), and many more records in Detailed_Call_Data__c (hundreds of thousands).

The purpose of your batch job is to link up (based on a phone number, which I really hope is an indexed field) the Detailed_Call_Data__c records to their corresponding Lines__c.

Running a batch job for each Lines__c is not going to be the most efficient way to do this. (For one thing, you'll hit the Apex Flex Queue limit really fast). Instead, I see a couple of viable options, which are not mutually exclusive.

Scheduled Incremental Update Batch

Run a batch on the Detailed_Call_Data__c every night.

Have it query for only records that aren't associated with a Lines__c already.

In execute(), collect the identifiers (phone numbers) for that batch of Detailed_Call_Data__c. Query for the matching Lines__c and build a Map<String, Lines__c> to collate the numbers to the lines. Then, iterate over the Detailed_Call_Data__c again, and populate the relationships to those Lines__c that were located.

Group Incoming Lines__c in Each Batch Job

Keep your current approach, except instead of passing a single Lines__c into your batch, pass a List<Lines__c>. In start(), collect the phone numbers of those Lines__c records and run a query for Detailed_Call_Data__c that matches any of them.

In execute(), build a Map<String, Lines__c> to collate the numbers to the lines. Then, iterate over your scope of Detailed_Call_Data__c records and assign each to the matching Lines__c.

Summary

Either way (or both), you'll massively reduce the number of Apex batch jobs you're running, and will likely get much better performance out of it.

1
  • David, many thanks for sharing your knowledge. Your detailed explanation is exactly what I needed. Thanks to all the contributors!
    – wmin
    Nov 1, 2019 at 11:31

You must log in to answer this question.

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