Java - Cron job - если экземпляр запускает пакетное задание, запретите другому экземпляру делать то же самое - PullRequest
1 голос
/ 27 января 2020

У меня есть приложение, работающее в двух экземплярах, и единственное взаимодействие между экземплярами заключается в том, что они работают в одной базе данных. У меня есть несколько пакетных заданий. Например: скопировать записи из базы данных в файл и доставить файл на сервер. Поскольку для обоих экземпляров существует общая база данных, я пытаюсь записать в таблицу, что задание было запущено. По сути, условие триггера - такая запись не существует в данной таблице. Как я могу выполнить это атомарно, то есть проверить таблицу, что задание не было запущено, а затем вставить в таблицу?

Ответы [ 2 ]

1 голос
/ 28 января 2020

Если у вас есть запланированное задание, которое нужно запускать, например, каждые 15 секунд и которое должно запускаться только на одном экземпляре приложения, тогда вы можете использовать ShedLock

Это довольно простой механизм, который в основном делает то же, что вы упомянули - создает таблицу (на самом деле, вам нужно создать ее один раз) и периодически получает блокировку для нее. Вы можете установить, сколько времени он должен быть заблокирован, и некоторые другие вещи.

Работает как с SQL, так и без SQL dbs, например, Postgres и Mon go и требует только одну аннотацию @SchedulerLock. Смотрите ниже:

    @Scheduled(fixedRateString = "PT15S")
    @SchedulerLock(name = "copy_records")
    public void copyRecords()
    {
        // do smth on a single instance of an app only
    }
1 голос
/ 27 января 2020

Pesimisti c блокировка может помочь здесь:

  • Создать выделенную таблицу, содержащую запись блокировки, с последним временем выполнения
  • В выполнение по расписанию, получение (или создание) записи блокировки над введенной EntityManager с помощью LockModeType.PESSIMISTIC_WRITE.
  • Проверка времени выполнения записи блокировки: если она была недавно обновлена, задание должно быть уже выполнено в другом экземпляре
  • В противном случае выполните задание и обновите время последнего выполнения записи блокировки впоследствии.

См. Режимы блокировки (Java EE Tutorial) для более подробной информации.

Пример применения такого механизма блокировки: таблица DATABASECHANGELOGLOCK от Liquibase, документально подтвержденная здесь .

...