Rerunning Failed Jobs - Spring Batch Part 5

If the Spring Job fails, Spring Batch Job uses Job Repository to know where the Job Failed, and restarts from that step.

Lets see an example on how it is done:


Note: I have dropped the Spring Job Repository tables just to able to rerun the application just to make it easy to rerun the Job

DROP TABLE BATCH_STEP_EXECUTION_CONTEXT ;
DROP TABLE BATCH_STEP_EXECUTION ;
DROP TABLE BATCH_JOB_INSTANCE ;
DROP TABLE BATCH_JOB_EXECUTION_PARAMS ;
DROP TABLE BATCH_JOB_EXECUTION_CONTEXT ;
DROP TABLE BATCH_JOB_EXECUTION ;


// Toggle true/false to test rerunning failed jobs
private boolean throwException = true;
@Bean
public Step packageStep() {
return this.stepBuilderFactory.get("packageStep").tasklet(new Tasklet() {
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
if(throwException){
throw new RuntimeException("Exception while Packaging");
}
System.out.println("Packaging the gift with " + giftWrapper);
return RepeatStatus.FINISHED;
}
}).build();
}
Running the application by setting throwException=true.

Here is the output after running the application:

2020-07-19 14:59:10.211  INFO 6944 --- [           main] o.s.b.c.l.support.SimpleJobLauncher      : Job: [SimpleJob: [name=giftShopJob]] launched with the following parameters: [{giftWrapper=Golden Box}]
2020-07-19 14:59:10.383  INFO 6944 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Executing step: [readOrderStep]
Order Received
2020-07-19 14:59:10.419  INFO 6944 --- [           main] o.s.batch.core.step.AbstractStep         : Step: [readOrderStep] executed in 36ms
2020-07-19 14:59:10.439  INFO 6944 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Executing step: [packageStep]
2020-07-19 14:59:10.451 ERROR 6944 --- [           main] o.s.batch.core.step.AbstractStep         : Encountered an error executing step packageStep in job giftShopJob

java.lang.RuntimeException: Exception while Packaging
at com.ricsr.springbootdemo.SpringbootdemoApplication$2.execute(SpringbootdemoApplication.java:53) ~[main/:na]
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:407) ~[spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:331) ~[spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140) ~[spring-tx-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:273) ~[spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:82) ~[spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:375) ~[spring-batch-infrastructure-4.2.4.RELEASE.jar:4.2.4.RELEASE]
......

at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237) ~[spring-boot-2.3.1.RELEASE.jar:2.3.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) ~[spring-boot-2.3.1.RELEASE.jar:2.3.1.RELEASE]
at com.ricsr.springbootdemo.SpringbootdemoApplication.main(SpringbootdemoApplication.java:73) ~[main/:na]

2020-07-19 14:59:10.455  INFO 6944 --- [           main] o.s.batch.core.step.AbstractStep         : Step: [packageStep] executed in 16ms
2020-07-19 14:59:10.463  INFO 6944 --- [           main] o.s.b.c.l.support.SimpleJobLauncher      : Job: [SimpleJob: [name=giftShopJob]] completed with the following parameters: [{giftWrapper=Golden Box}] and the following status: [FAILED] in 152ms
2020-07-19 14:59:10.467  INFO 6944 --- [extShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
2020-07-19 14:59:10.483  INFO 6944 --- [extShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.

BUILD SUCCESSFUL in 6s
3 actionable tasks: 2 executed, 1 up-to-date
2:59:10 PM: Task execution finished 'SpringbootdemoApplication.main()'.


So, there was an exception, as expected, while running the packageStep and the deliveryStep was not executed. But the orderStep was executed.

Now, lets look at the tables:



BATCH_JOB_EXECUTION table tells us that the job has failed and the exception we got while running the Job.

While the BATCH_STEP_EXECUTION has information of the Steps of the Job which have executed either successfully or have failed:



Let us try rerunning the job by toggling our throwException flag to false.


2020-07-19 15:22:35.081  INFO 1520 --- [           main] c.r.s.SpringbootdemoApplication          : Started SpringbootdemoApplication in 1.497 seconds (JVM running for 1.801)
2020-07-19 15:22:35.085  INFO 1520 --- [           main] o.s.b.a.b.JobLauncherApplicationRunner   : Running default command line with: []
2020-07-19 15:22:35.975  INFO 1520 --- [           main] o.s.b.c.l.support.SimpleJobLauncher      : Job: [SimpleJob: [name=giftShopJob]] launched with the following parameters: [{}]
2020-07-19 15:22:36.003  INFO 1520 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Step already complete or not restartable, so no action to execute: StepExecution: id=37, version=3, name=readOrderStep, status=COMPLETED, exitStatus=COMPLETED, readCount=0, filterCount=0, writeCount=0 readSkipCount=0, writeSkipCount=0, processSkipCount=0, commitCount=1, rollbackCount=0, exitDescription=
2020-07-19 15:22:36.015  INFO 1520 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Executing step: [packageStep]
Packaging the gift
2020-07-19 15:22:36.031  INFO 1520 --- [           main] o.s.batch.core.step.AbstractStep         : Step: [packageStep] executed in 16ms
2020-07-19 15:22:36.043  INFO 1520 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Executing step: [deliveryStep]
Package out for delivery
2020-07-19 15:22:36.051  INFO 1520 --- [           main] o.s.batch.core.step.AbstractStep         : Step: [deliveryStep] executed in 8ms
2020-07-19 15:22:36.055  INFO 1520 --- [           main] o.s.b.c.l.support.SimpleJobLauncher      : Job: [SimpleJob: [name=giftShopJob]] completed with the following parameters: [{}] and the following status: [COMPLETED] in 64ms
2020-07-19 15:22:36.059  INFO 1520 --- [extShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
2020-07-19 15:22:36.067  INFO 1520 --- [extShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.

BUILD SUCCESSFUL in 4s


As you can see from the output, our orderStep was not executed. But the Job started from where it failed: it rerun the packageJob and then the deliveryJob.

Lets look at the tables:

BATCH_JOB_EXECUTION  has an entry for the successfully run job.


And so does the BATCH_STEP_EXECUTION 


This is a very useful feature of Spring Batch as you dont have to worry about rerunning already run Steps OR unable to rerun the failed Steps of a Job. 

Comments

Popular posts from this blog

Writing your own ejabberd Module

npm ECONNREFUSED error

Conditional Flow - Spring Batch Part 6