3

I have a batch class which we use to save data from csv to different objects. In the batch.execute, I put a condition to check if a data to be inserted meets the data type of the field its going to save. It returns a value (true or false). My problem is how do I jump from batch.execute to batch.finish if the condition returns false to prevent from inserting all other data.

How do I stop Batch.Execute and jump from Batch.Execute to Batch.Finish?

2 Answers 2

5

Jumping from Batch.Execute to Batch.Finish is not possible. If there is any unhandled error i.e. any exception was thrown in code within execute method data changes made within that execute block are rolled back and that particular batch is marked for failure(just that execute instance not all)

You can use system.abortjob within execute method to immediately abort the job but that will not call finish method. But you can encapsulate processing that you are doing in finish method by creating a new private method and then call if from execute and finish both. From execute this new method will be called conditionally before you abort the job.

Here is code sample to clarify this.

public class CSVBatch implements Database.Batchable<String>
{
    public Iterable<String> start(Database.BatchableContext BC)
    {
        List<String> csvLines = new List<String>();
        for(integer i = 1; i < 500; i++)
            csvLines.add(String.valueOf(i));
        return csvLines;
    }

    public void execute(Database.BatchableContext BC, List<String> scope)
    {
        for(String s : scope)
        {
            if(s == '120')
            {
                //case 1 - We don't want to process further in batch
                //Do finish processing here 
                mycustomfinish();

                //After that abort the Job
                system.abortJob(BC.getJobId());   
            }
            else if(s == '420')
            {
                //Case 2 - We just want to skip current batch
                throw new AppException('Skipped current batch');
            }
            else
            {
                //do some processing    
            }
        }
    }

    public void finish(Database.BatchableContext BC)
    {
        mycustomfinish();   
    } 

    private void mycustomfinish()
    {
        system.debug('finish called');    
    }

    public class AppException extends Exception{}
}
1
  • My problem is that the method I'm trying to call is also batch so redirecting it to a non batch method will be useless.
    – Micz Domz
    Commented Sep 3, 2015 at 9:55
2

A very simple solution would just be to implement Database.Stateful and then have a boolean flag for your exit condition. The execute statement would of course fire for every remaining iteration, but you could prevent anything from happening.

public void execute(Database.BatchableContext BC, List<String> scope)
{
    if(exitCondition){return;}
    //otherwise do things
    ...
}
1
  • I don't think this is an efficient design since if there are lot of batches we will be wasting Daily org limit for Async Execution. The maximum number of asynchronous Apex method executions (batch Apex, future methods, Queueable Apex, and scheduled Apex) per a 24-hour period: 250,000 or the number of user licenses in your organization multiplied by 200, whichever is greater. developer.salesforce.com/docs/atlas.en-us.apexcode.meta/…
    – Amit Jain
    Commented May 28, 2020 at 11:01

You must log in to answer this question.

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