2

We run several spring batch jobs within tomcat in the same web application that serves up our UI. Lately we have been adding many more jobs and we are noticing that when we patch our app, several jobs may get stuck in a STARTING or STARTED status. Many of those jobs ensure that another job is not running before they start up, so this means after we patch the server, some of our jobs are broken until we manually run SQL to update the statuses of the jobs to ABANDONED or STOPPED.

I have read here that JobScope and StepScope jobs don't play nicely with shutting down.

That article suggests not using JobScope or StepScope but I can't help but think that this is a solved problem where people must be doing something when the application exits to prevent this problem.

Are there some best practices for handling this scenario? What are you doing in your applications?

We are using spring-batch version 3.0.3.RELEASE

Josh Chappelle
  • 1,558
  • 2
  • 15
  • 37
  • the scope Problems in the referenced article are not responsible for STOP not working, the job configuration there is just plain wrong (the scopes are not used and not useful in the provided example) – Michael Pralow Nov 19 '15 at 07:15

1 Answers1

3

I will provide you an idea on how to solve this scenario. Not necessarily a spring-batch solution.

Everytime I need to add jobs in an application I do as this:

  1. Create a table to control the jobs (queue, priority, status, etc.)
  2. Create a JobController class to manage all jobs
  3. All jobs are defined by the status R-running, F-Finished, Q-Queue (you can add more as you need like aborted, cancelled, etc) (the jobs control these statuses)
  4. The jobController must be loaded only once, you can define it as a spring bean for this
  5. Add a boolean attribute to JobController to inform if you already checked the jobs when you instantiate it. Set it to false
  6. Check if there are jobs with the R status which means that in the last stop of the server they were running so you update every job with this R status to Q and increase their priority so it will get executed first after a restart of the server. This check is inside the if for that boolean attribute, after the check set it to true.

That way every time you call the JobController for the first time and there are unfinished jobs from a server crash you will be able to set then all to a status where it can be executed again. And this check will happens only once since you will be checking that boolean attribute.

A thing that you should be aware of is caution with your jobs priority, if you manage it wrong you may run into a starvation problem.

You can easily adapt this solution to spring-batch.

Hope it helps.

Jorge Campos
  • 22,647
  • 7
  • 56
  • 87
  • I appreciate you taking the time to give me a thoughtful answer. I can implement my own solution to this by setting all statuses to ABORTED if they are set to STARTING or STARTED when the app starts, maybe with a ServletContextListener or some kind of startup listener in Spring. I was hoping for a more elegant solution. Again thanks for the comment. – Josh Chappelle Nov 19 '15 at 15:43