Stop and Fail Transitions - Spring Batch Part 7

Lets modify our throwException boolean to true and run application from our previous blog post
// Toggle true/false to test rerunning failed jobs
private boolean throwException = true;
In case of an exception thrown by the packageStep, we go to manualPackageStep and the workflow just stops there. But the steps to deliver/pickup have not been executed. If you try rerunning by setting the throwException = false, it wont run. 

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

Also, if you check the Step status of packageStep in BATCH_STEP_EXECUTION table, it will show that the Step was ABANDONED and the status of the Job in BATCH_JOB_EXECUTION  table, it will be COMPLETED. 
But this is not what we want. We want to manually fix the packaging and then send it out either for delivery or for pickup.

The problem is that we are ending our condiotional block using end(), which Spring Batch considers a successful flow.


We can fix the problem using stop() method. So, in our case, if the packageStep fails, we want someone to manually fix the problem, right?

@Bean
public Job packageJob(){
return this.jobBuilderFactory.get("giftShopJob").start(readOrderStep())
.next(packageStep())
.on("FAILED").stop()
.from(packageStep())
.on("*").to(pickupOrDeliveryDecider())
.on("DELIVER").to(deliveryStep())
.from(pickupOrDeliveryDecider())
.on("PICKUP").to(pickupStep())
.end()
.build();
}
Now if you try rerunning the application, you see the following output:

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

2020-07-20 00:00:21.601  INFO 13740 --- [           main] o.s.b.c.l.support.SimpleJobLauncher      : Job: [FlowJob: [name=giftShopJob]] launched with the following parameters: [{}]
2020-07-20 00:00:21.660  INFO 13740 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Executing step: [readOrderStep]
Order Received
2020-07-20 00:00:21.683  INFO 13740 --- [           main] o.s.batch.core.step.AbstractStep         : Step: [readOrderStep] executed in 22ms
2020-07-20 00:00:21.700  INFO 13740 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Executing step: [packageStep]
2020-07-20 00:00:21.712 ERROR 13740 --- [           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:61) ~[main/:na]
at ..........
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:108) ~[main/:na]

2020-07-20 00:00:21.714  INFO 13740 --- [           main] o.s.batch.core.step.AbstractStep         : Step: [packageStep] executed in 14ms
2020-07-20 00:00:21.724  INFO 13740 --- [           main] o.s.b.c.l.support.SimpleJobLauncher      : Job: [FlowJob: [name=giftShopJob]] completed with the following parameters: [{}] and the following status: [STOPPED] in 85ms
2020-07-20 00:00:21.728  INFO 13740 --- [extShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
2020-07-20 00:00:21.742  INFO 13740 --- [extShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.

BUILD SUCCESSFUL in 4s

If you look at the output of BATCH_JOB_EXECUTION , you see that the status of the job is STOPPED.


Let us now manually fix the error. I mean set  throwException = false; and rerun

2020-07-20 00:04:23.034  INFO 16244 --- [           main] o.s.b.c.l.support.SimpleJobLauncher      : Job: [FlowJob: [name=giftShopJob]] launched with the following parameters: [{}]
2020-07-20 00:04:23.077  INFO 16244 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Step already complete or not restartable, so no action to execute: StepExecution: id=63, 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-20 00:04:23.090  INFO 16244 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Executing step: [packageStep]
Packaging the gift
2020-07-20 00:04:23.110  INFO 16244 --- [           main] o.s.batch.core.step.AbstractStep         : Step: [packageStep] executed in 20ms
Customer choose: DELIVER
2020-07-20 00:04:23.126  INFO 16244 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Executing step: [deliveryStep]
Package out for delivery
2020-07-20 00:04:23.134  INFO 16244 --- [           main] o.s.batch.core.step.AbstractStep         : Step: [deliveryStep] executed in 8ms
2020-07-20 00:04:23.140  INFO 16244 --- [           main] o.s.b.c.l.support.SimpleJobLauncher      : Job: [FlowJob: [name=giftShopJob]] completed with the following parameters: [{}] and the following status: [COMPLETED] in 77ms
2020-07-20 00:04:23.144  INFO 16244 --- [extShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
2020-07-20 00:04:23.153  INFO 16244 --- [extShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.

As you can see, the job continued from the packageStep and COMPLETED this time. 

Lets also take a look at the BATCH_JOB_EXECUTION  table:

Also, I suggest you to take a look at BATCH_STEP_EXECUTION table:


You can also FAIL a Job. 
@Bean
public Job packageJob(){
return this.jobBuilderFactory.get("giftShopJob").start(readOrderStep())
.next(packageStep())
.on("FAILED").fail()
.from(packageStep())
.on("*").to(pickupOrDeliveryDecider())
.on("DELIVER").to(deliveryStep())
.from(pickupOrDeliveryDecider())
.on("PICKUP").to(pickupStep())
.end()
.build();
}
Both STOP and FAIL allows us to rerun the application. We should not, in any case, set up a job which transitions to a state where we are unable to rerun it if it fails. We should be able to revive from a failed job.

Comments

Popular posts from this blog

Writing your own ejabberd Module

npm ECONNREFUSED error

Conditional Flow - Spring Batch Part 6