spring-batch icon indicating copy to clipboard operation
spring-batch copied to clipboard

Duplicated job execution for single job instance.

Open Ceglee opened this issue 5 years ago • 4 comments

Bug description There is a chance, to have more than one actively running job executions, for a one job instance, which has restartable option set to false (preventRestart() being called).

Environment 4.2.1.RELEASE, Java 8u261, Oracle, 4 application instances running at the same time.

Steps to reproduce Just create a job with single step, prevent it from restart and try to run it, in more than one java process at the same time. At some point you should be able to reproduce it.

Expected behavior It should create only one job execution for each job instance.

Minimal Complete Reproducible example You just have to configure any batch job, just be sure that you are using the same database for all processes.

Cause of the problem Problem lies in SimpleJobRepository class in createJobExecution method. You are not checking there, whether job is restartable or not. You are only doing it at level of SimpleJobLauncher, which is calling createJobExecution, but this is not enough. You are setting proxy transaction only over the SimleJobRepository, so state in run method from SimpleJobLauncher might change. Please take a look on following image. Assuming that processes (or even threads) will do it in following order and the 1 process will not yet start its job execution, job instance will end up with having two job executions.

image

Btw. in your documentation (https://docs.spring.io/spring-batch/docs/current/reference/html/schema-appendix.html) you are missing unique constraint in BATCH_JOB_INSTANCE definition.

Ceglee avatar Oct 07 '20 08:10 Ceglee

I think, in method createJobExecution changing this condition: if (execution.isRunning() || execution.isStopping()) {...} to something like this: if (execution.isStarting() || execution.isRunning() || execution.isStopping()) {...} might help.

Ceglee avatar Oct 07 '20 08:10 Ceglee

I also encountered this problem with restartable job. (createJobExecution could be called from different process before starting the execution.) This behavior seems introduced from https://github.com/spring-projects/spring-batch/pull/659.

Adding the guard condition execution.isStarting() in createJobExecution sounds good to me. The implementation may be like as follows, considering the usage of startTime?

public boolean isStarting() {
	return startTime == null && status == BatchStatus.STARTING;
}

cormoran avatar Dec 12 '20 07:12 cormoran

Any update on this issue. We still have similar issue. Also raised new issue with more details - https://github.com/spring-projects/spring-batch/issues/3966

baalaad avatar Jul 22 '21 20:07 baalaad

This is related to #1483 , and can also be fixed by PR #4113

lcmarvin avatar May 12 '22 08:05 lcmarvin

@Ceglee Thank you for reporting this issue! And thanks to @cormoran and @lcmarvin for the follow up and the PRs 👍

#1483 and #4113 have now been resolved, can you please give a try with the latest 5.0.0 snapshots and share your feedback? Thank you upfront!

fmbenhassine avatar Nov 18 '22 16:11 fmbenhassine

The fixes have been released in v5.0.0.

If you still have the issue, please add a comment here and we will re-open the issue for further investigation.

fmbenhassine avatar Nov 24 '22 04:11 fmbenhassine