Skip to content

Prevent step execution leakage between flow job executions - #5528

Open
jjj-n wants to merge 1 commit into
spring-projects:mainfrom
jjj-n:codex/spring-batch-5514-flow-context-cleanup
Open

jjj-n wants to merge 1 commit into
spring-projects:mainfrom
jjj-n:codex/spring-batch-5514-flow-context-cleanup

Conversation

@jjj-n

@jjj-n jjj-n commented Sep 8, 2026

Copy link
Copy Markdown

When no transition matches a step's exit status, SimpleFlow.nextState() throws outside the block that closes the executor. The static JobFlowExecutor holder can then expose the failed step to a subsequent job execution on the same thread, which may mark it ABANDONED and prevent restart.

This change closes the executor when transition lookup fails and scopes the thread-local holder to each executor. Thread isolation within an executor is preserved for parallel flows.

Four JDBC-backed regression tests cover preserving another job's persisted step status and version, restarting after an unmatched transition, exceptional cleanup, and isolation between executors. The new tests fail against the original implementation and pass with this change.

Fixes #5514

Validation on Windows with JDK 25:

  • Flow-related tests: 64 tests, 0 failures/errors, 4 skipped.
  • Core unit suite: 832 tests, 0 failures/errors, 47 skipped.
  • Selected restart, partition, nested/async scope, and H2/HSQL repository integration tests: 15 tests, all passing.
  • The unchanged issue reporter's MCVE, using the locally built 6.1.0-SNAPSHOT, re-runs the failed step, preserves the first job's FAILED status after another job runs, and no longer produces the stale-copy optimistic locking failure. The catch-all control still behaves correctly.

The full mvn install attempt stopped at two failures in the unchanged infrastructure module: AbstractFileItemWriterTests.testFailedFileDeletionThrowsException and StaxEventItemWriterTests.testFailedFileDeletionThrowsException. Both stub File.delete(), while the implementations call Files.delete(). A follow-up all-module test run with -Dmaven.test.failure.ignore=true reported only these same two failures; the core, test-support, and integration modules had no failures. The full integration/functional suite has not passed locally.

Close the flow executor when transition lookup fails and keep the step
execution holder local to each executor while preserving thread isolation.

Add JDBC-backed regression coverage for restart, unrelated job execution,
exceptional cleanup, and executor isolation.

Fixes spring-projects#5514

Signed-off-by: 郑朝钦 <1357598741@qq.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

JobFlowExecutor leaks a StepExecution across job executions on a shared thread when no transition matches a step's ExitStatus

1 participant