Files

47 lines
3.4 KiB
Plaintext

# Spring Batch 6.0's fix: JobOperator#recover, then a normal restart
$ java -jar target/spring-batch-partitioning-1.0.0.jar --spring.profiles.active=recover \
--recover.job-execution-id=1 --partition.shards-dir=./data/shards-small \
--partition.grid-size=4 --partition.pool-core-size=4 --partition.pool-max-size=4
RECOVER: before -> status=FAILED
RECOVER: step=ordersManagerStep status=FAILED
RECOVER: step=ordersWorkerStep:partition3 status=STARTING
RECOVER: step=ordersWorkerStep:partition2 status=STARTING
RECOVER: step=ordersWorkerStep:partition1 status=COMPLETED
RECOVER: step=ordersWorkerStep:partition0 status=STARTING
2026-09-14T09:13:31.156Z INFO 3377 --- [ main] o.s.b.c.l.s.TaskExecutorJobOperator : Recovering job execution: JobExecution: id=1, version=3, startTime=2026-09-14T09:11:21.331474360, endTime=2026-09-14T09:11:21.965090481, lastUpdated=2026-09-14T09:11:21.966521177, status=FAILED, exitStatus=exitCode=FAILED;exitDescription=org.springframework.batch.core.job.JobExecutionException: Partition handler returned an unsuccessful step
RECOVER: after -> status=FAILED
RECOVER: step=ordersManagerStep status=FAILED
RECOVER: step=ordersWorkerStep:partition3 status=FAILED
RECOVER: step=ordersWorkerStep:partition2 status=FAILED
RECOVER: step=ordersWorkerStep:partition1 status=COMPLETED
RECOVER: step=ordersWorkerStep:partition0 status=FAILED
JOB FINISHED: id=33 status=COMPLETED exitCode=COMPLETED
recover() walked the stuck JobExecution's StepExecutions and force-closed the three still at
STARTING to FAILED -- nothing else changed. RecoveryRunner runs at @Order(0); OrderIngestRunner
then runs its normal start() immediately after, in the same JVM, against the same shardsDir, and
this time it succeeds: a brand-new JobExecution (id=33) completes.
--- BATCH_STEP_EXECUTION after recovery + restart: which partitions actually reran ---
$ java -cp h2-2.4.240.jar org.h2.tools.Shell -url jdbc:h2:file:./data/rejecttest -user sa -password "" \
-sql "SELECT JOB_EXECUTION_ID, STEP_EXECUTION_ID, STEP_NAME, STATUS, READ_COUNT FROM BATCH_STEP_EXECUTION WHERE JOB_EXECUTION_ID IN (1,33) ORDER BY JOB_EXECUTION_ID, STEP_EXECUTION_ID;"
JOB_EXECUTION_ID | STEP_EXECUTION_ID | STEP_NAME | STATUS | READ_COUNT
1 | 1 | ordersManagerStep | FAILED | 5000
1 | 2 | ordersWorkerStep:partition3 | FAILED | 0
1 | 3 | ordersWorkerStep:partition2 | FAILED | 0
1 | 4 | ordersWorkerStep:partition1 | COMPLETED | 5000
1 | 5 | ordersWorkerStep:partition0 | FAILED | 0
33 | 33 | ordersManagerStep | COMPLETED | 15000
33 | 34 | ordersWorkerStep:partition3 | COMPLETED | 5000
33 | 35 | ordersWorkerStep:partition2 | COMPLETED | 5000
33 | 36 | ordersWorkerStep:partition0 | COMPLETED | 5000
33 | 37 | reportStep | COMPLETED | 0
JobExecution 33 has exactly three new worker StepExecutions -- partition3, partition2, partition0,
the ones recover() marked FAILED. There is no new StepExecution for partition1: it stayed
COMPLETED from JobExecution 1 and was correctly skipped. Restart-only-the-failed-partition is not
a promise in the reference docs here -- it is what this table shows actually happened.