Java - Cron job - if an instance triggers a batch job, prevent other instance from doing the same

1.5k views Asked by At

I have an application running on two instances and only communication between the instances is that they operate on a single database. I have few batch jobs running on it. For example: Copy records from the database to a file and deliver the file to a server. Since there is a common database for both the instances, I'm trying to write to a table that job has been triggered. Basically, a trigger condition is such a record doesn't exist on a given table. How can I perform this atomically, i.e., check the table that job hasn't been triggered then insert into table?

2

There are 2 answers

4
Random Guy On BEST ANSWER

If you have a scheduled task that needs to be launched, for example, every 15 seconds and should only run on a single instance of app, then you can use ShedLock

It's pretty simple mechanism that basically does the same that you mentioned - creates a table (actually, you need to create it once) and periodically acquires lock for it. You can set up for how much time it should be locked and some others things.

Works with both SQL and NoSQL dbs, like Postgres and Mongo and requires just one annotation @SchedulerLock. See below:

    @Scheduled(fixedRateString = "PT15S")
    @SchedulerLock(name = "copy_records")
    public void copyRecords()
    {
        // do smth on a single instance of an app only
    }
0
Peter Walser On

Pesimistic locking can help here:

  • Create a dedicated table that holds a lock record, with the last execution time
  • In the scheduled execution, aquire (or create) the lock record over an injected EntityManager with LockModeType.PESSIMISTIC_WRITE.
  • Check the execution time on the lock record: if it was recently updated, the job must have already been run on another instance
  • Otherwise, execute the job, and update the last execution time on the lock record afterwards.

See Lock Modes (Java EE Tutorial) for more details an options.

Example application of such a locking mechanism: Liquibase's DATABASECHANGELOGLOCK table, documented here.