Мы используем кварц для планирования заданий с MariaDB внизу в настройке из нескольких узлов. Мы также используем его как систему очередей. Самая главная причина этого в том, что у нас уже есть кварц в нашем сервисе, и у нас пока нет очереди.
Мы получаем много запросов, очень часто одновременно с одним и тем же id бизнес-объекта, который используется для генерации имени задания для уникальности.
try {
quartzServce.scheduleJob(job, trigger);
log.info("job: {} has been scheduled", id);
} catch (ObjectAlreadyExistsException ex) {
log.warn(DUPLICATE_ENTRY_MESSAGE, job.getKey(), trigger.getKey());
} catch (Exception ex) {
throw new RuntimeException(ex);
}
quartzService.scheduleJobs просто:
public void scheduleJob(JobDetail jobDetail, Trigger trigger) throws SchedulerException {
schedulerFactory.getScheduler().scheduleJob(jobDetail, trigger);
}
Как видите, мы перехватываем ObjectAlreadyExistsException и заглушаем его на уровне предупреждения, поскольку мы не рассматриваем его как ошибок, но время от времени мы все еще получаем SQLIntegrityConstraintViolationException, завернутый в JobPersistenceException с сообщением:
Couldn't store job: (conn=435654) Duplicate entry '{our key is over here}' for key 'PRIMARY' [See nested exception: java.sql.SQLIntegrityConstraintViolationException: (conn=435654) Duplicate entry '{our key is over here}' for key 'PRIMARY']
Я предполагаю, что между проверкой существования и фактической вставкой другому узлу удается вставить строку для тот же идентификатор.
Так как я не очень люблю проверять сообщение в исключении на предмет чего-то вроде «Дублированная запись» и заглушать исключение с помощью уровня предупреждения в этом условии, я ищу другой решение, может быть, кварцевую конфигурацию?