| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
Signed-off-by: jjh75607 <jjh7560734@gmail.com>
Resolve conflict with eec42cb (Fix inaccurate exception message in TaskExecutorJobLauncher). The message improvement is kept: the running JobExecution, not the JobInstance, is reported. The new TaskExecutorJobLauncherTests now stubs getLastJobExecution instead of getJobExecutions, which createJobExecution no longer calls. Signed-off-by: jjh75607 <jjh7560734@gmail.com>
| Back | FazBrowse Home | New Git URL |
Resolves #5495
When a job instance is restarted, TaskExecutorJobLauncher.createJobExecution reads the instance history twice: getJobExecutions(jobInstance) for the running / UNKNOWN / COMPLETED / ABANDONED checks, then getLastJobExecution(jobInstance) for the step checks and the execution context. Since SimpleJobRepository extends SimpleJobExplorer, the first call hydrates every past execution with its job instance, step executions and both execution contexts, so the number of statements per launch grows with the number of past executions. Before 6.0 this check lived in SimpleJobRepository and went through jobExecutionDao.findJobExecutions, which only loaded the job parameters per execution; moving it to the launcher in 90d8959 is where the slope went from one to eight statements per past execution.
This change drops the first read and runs the status checks against the last execution only. A new execution is only created once these checks pass on the previous one, so on the launcher's own path the last execution is the only one that can be running, UNKNOWN or COMPLETED.
Measured with the reproducer from #5495 (same instance restarted 12 times, statements counted with datasource-proxy on H2), on main before and after this change:
launch | before | after 1 | 32 | 32 2 | 50 | 41 6 | 82 | 41 12 | 130 | 41What does change, and I want to be explicit about it: executions that are not the last one are no longer inspected. I built every combination of two past executions (8 statuses in each position) directly through JobRepository and compared main with this branch. The 35 cases where the older execution is FAILED or STOPPED, or where there is a single execution, behave identically, including the step status checks, preventRestart(), empty identifying parameters and carrying over the last execution context. The 6 cases where the older execution is running, COMPLETED, ABANDONED or UNKNOWN while a newer FAILED one exists were rejected on main and now proceed. Such a history cannot be produced through the launcher; it takes abandon on an older execution after the instance has already been restarted, a direct JobRepository.createJobExecution call, or two launches of the same instance racing past the check, which the existing code already only guards against probabilistically (see the comment above jobRepository.createJobExecution at the end of the method). If you would rather keep inspecting the full history, the alternative is a repository method that returns executions without hydrating them, which is an API addition I did not want to make on my own. Happy to go that way if you prefer.
Tests added to TaskExecutorJobOperatorTests for the last execution being running, being complete, and for a restart after several failed executions; these pass on main as well and are there to pin the behaviour. The spring-batch-core, spring-batch-integration and spring-batch-test suites pass. Also removes the now unused java.util.List import.
Update (2026-08-28): merged main to resolve a conflict with eec42cb, which changed the running-execution message inside the loop this PR removes. The improved message is kept (lastJobExecution instead of jobInstance), and the new TaskExecutorJobLauncherTests now stubs getLastJobExecution instead of getJobExecutions, which createJobExecution no longer calls. Its assertions are unchanged.