Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SynchronizeStatus in MongoJobExecutionDao is not upgrading the status of the JobExecution #4760

Closed
denis-yablonsky opened this issue Feb 7, 2025 · 2 comments

Comments

@denis-yablonsky
Copy link

Bug description
Unlike the JdbcJobExecutionDao, the MongoJobExecutionDao is not "upgrading" the status of the jobExecution that was passed in. This can cause behavior where a job status can go from STOPPING back to STARTED by an asynchronous update.

Environment
Spring Batch version: 5.2.1
Java version:17.0.8
which database you use: Mongo 8.0.1

Steps to reproduce
Steps to reproduce the issue:

  1. Start a Job using JobLauncher
  2. Attempt to stop the job using JobOperator::stop
  3. Verify the status in the jobExecution is updated to STOPPING via the JobExplorer
  4. Wait for end of step to update JobExecution
  5. Verify the status in the jobExecution is downgraded to STARTED via the JobExplorer

Expected behavior
I would expect the status to not be allowed to downgrade because that is the behavior of the JDBC implementation.

@denis-yablonsky denis-yablonsky added status: waiting-for-triage Issues that we did not analyse yet type: bug labels Feb 7, 2025
@denis-yablonsky
Copy link
Author

denis-yablonsky commented Feb 8, 2025

I was able to fix this locally by modifying the synchronizeStatus method to either upgrade the local jobExecution status or update the status in database:

public void synchronizeStatus(JobExecution jobExecution) {
      var currentJobExecution = getJobExecution(jobExecution.getId());
      if ((currentJobExecution != null) && currentJobExecution.getStatus().isGreaterThan(jobExecution.getStatus())) {
          jobExecution.upgradeStatus(currentJobExecution.getStatus());
      } else {
          Query query = query(where("jobExecutionId").is(jobExecution.getId()));
          Update update = Update.update("status", jobExecution.getStatus());
          this.mongoOperations.updateFirst(query, update,
                  org.springframework.batch.core.repository.persistence.JobExecution.class,
                  JOB_EXECUTIONS_COLLECTION_NAME);
      }
  }

@fmbenhassine
Copy link
Contributor

Thank you for reporting this! The current mongo implementation is incorrect compared to the jdbc one. In fact, the jdbc implementation upgrades the job execution in memory while the mongo one updates the job execution in the database. I think I misunderstood the contract when I implemented the method back then (probably the contact should be clearer in that regard).

Anyway, I will fix the mongo implementation and make it consistent with the jdbc one.

@fmbenhassine fmbenhassine added in: core related-to: job-repository and removed status: waiting-for-triage Issues that we did not analyse yet labels Feb 24, 2025
@fmbenhassine fmbenhassine added this to the 5.2.2 milestone Feb 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants