0

I have a batch Class and Schedular Class. I am calling Batch class From Schedular class Multiple Time in Execute method.Is this a good practice? In Batch class i am doing callout and insert/update records in Salesforce. Or i should call the Batches in chaining one after the another in Finish method of batch class by doing batch chaining.Which approach is better. PFB the sample code.

I am hitting the Same endpoint with Different parameter because Json is returning lots of data and the records is different for each batch.

Batch Class:

    global class Batch_To_Insert implements Database.Batchable<sObject>, Database.AllowsCallouts, Database.stateful{
    global integer i=0; 
    global string endpointToHit='';
    global Batch_To_InsertContacts(String endpointToBeHit){
        this.endpointToHit = endpointToBeHit;
        system.debug('endpointToHit='+endpointToHit);
    }
    global List<Contact> start(Database.BatchableContext BC)
    {
        system.debug('in start;');
        system.debug('endpointToHit='+endpointToHit);
        //Making a callout for Security Token
        //
        return new List<Contact>();
    }

    global void execute(Database.BatchableContext BC, List<Contact> contactList) {
        system.debug('inside execute='+contactList.size());
        try{ if(contactList.size()>0){              update contactList;    } } catch(Exception e){

        }                   
    }

    global void finish(Database.BatchableContext BC) {
        system.debug('in finish;');    

    }
}

Schedular class

    global class Batch_To_Insert_Schedular implements Schedulable{
    global void execute(SchedulableContext sc) {
    string endpoint1='https://xxxx.com/GetMemberStatusData?company=1&CampaignQueueStatusId=Y&FinalOutcomeStatus=In%20Progress&CampaignCategory=Welcome%20Call';
    string endpoint2='https://xxxx.com/GetMemberStatusData?company=1&CampaignQueueStatusId=Y&FinalOutcomeStatus=In%20Progress&CampaignCategory=Schedule%20Appointment';
    string endpoint3='https://xxxx.com/GetMemberStatusData?company=1&CampaignQueueStatusId=Y&FinalOutcomeStatus=In%20Progress&CampaignCategory=Health%20Risk%20Assessment';



    Batch_To_Insert obj1 = new Batch_To_Insert(endpoint1);
      Database.executeBatch(obj1);
    Batch_To_Insert obj2 = new Batch_To_Insert(endpoint2); 
      Database.executeBatch(obj2);
    Batch_To_Insert obj3 = new Batch_To_Insert(endpoint3); 
      Database.executeBatch(obj3);

   }
}

closed as unclear what you're asking by Pranay Jaiswal, battery.cord, glls, David Reed, dphil Dec 6 '18 at 19:40

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • is there any dependencies between these batches? – rahul gawale Dec 4 '18 at 11:58
  • one is batch class and another is schedular class.i am calling batch class from schedular class. – Gourishankar Dec 4 '18 at 12:00
  • 1
    In your case I doubt whether all batches from obj1, obj2 will run at a time and might cause read timed out error. – Manu Tej Dec 4 '18 at 12:23
  • 2
    Neither approach is unambiguously better without more detail on the batches involved. If they are operating on the same or related records, I would have some concern about the possibility of lock contention with the parallel approach. – David Reed Dec 4 '18 at 14:24
  • 1
    @Gourav My comment above states that I do not believe you have provided enough information to determine an optimal approach. Regardless, this is an implementation where, I would expect, every approach would involve one trade-off or another. While we can provide answers to specific questions here if you shed more light, more freewheeling conversations about different design patterns in the context of your specific requirements are probably best suited for your team environment. – David Reed Dec 6 '18 at 12:50
2

It is legal to enqueue five Batches in a Schedulable context. It may not be wise, and it may not lead to the results you expect - you shouldn't rely on the batches to execute at exactly the same time or finish at the same time, and you you should absolutely be aware of the potential for lock contention if the batches operate on the same set of records.

It is also legal to chain one Batch class BatchA into another Batch class BatchB by calling Database.executeBatch(new BatchB(), 200); from the finish() method of BatchA.

It is also legal to make up to 100 total callouts from a single iteration of a batch class, subject to the overall callout time limit, and those callouts don't have to be to the same endpoint.

The selection of the preferred architecture is highly dependent on what the batch classes do. Your sample code tells us almost nothing about your use case other than that you are calling several different endpoints.

The optimal architecture might be to run a single batch class that makes all five callouts for each record in its scope (and consequently runs at a low batch size to handle limits). Or it might be to process all the records through each callout in sequence by using batch chaining - if, for example, the same record set needs the be processed by all five callouts, and if the action of one callout depends on the result of a previous one. Or it might be that each batch class operates on a completely different record set and none of them relate to one another, so they can safely run in parallel for more performance.

It's highly fact-dependent and no one here can solve that architecture-level problem for you without a lot more detail. Even then, this issue reaches the level of solution architecture where it is probably best solved internally, with an understanding of the full scope and objectives of the solution.

1

You seem to have some design/implementation issue here. Batch classes are not meant to be invoked the way you are doing it or they don't need to be chained. Batch class by definition is:

A developer can now employ batch Apex to build complex, long-running processes that run on thousands of records on the Lightning Platform. Batch Apex operates over small batches of records, covering your entire record set and breaking the processing down to manageable chunks.

In a batch class, you will fetch records using a certain criteria and then accordingly perform further operation. If you always invoke the same endpoint, then you don't need to invoke the batch specifically individually, instead you can schedule the batch to be invoked at regular intervals.

Also take a look at Batch Apex Governor Limits in the documentation to read through in details about how batch classes are queued and processed by the platform.

I will recommend to review your use case and see if you need a batch class implementation or a Queueable Apex.

  • I am not hitting the same endpoint everytime. Instead its the same endpoint with different parameter so i am getting the different records for different batches.Provide me the best solution for this case.Please don't provide the generalize answer. – Gourishankar Dec 6 '18 at 7:11
  • 1
    You should provide these details in your original question then. In its current form you have not mentioned that and have only asked if it’s a good practice as written or not. Then you haven’t mentioned if records being operated are same, related or not. Even if you are hitting same endpoint with different parameters, you need to still redesign your approach of how you should be performing the callouts. What you have currently does not seem to be an optimal approach. – Jayant Das Dec 6 '18 at 12:32
  • since i know that it might not be optimal approach i am asking for solution.can you help on that.. – Gourishankar Dec 6 '18 at 12:45

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