Исключение повторяющейся записи при попытке создать новую вакансию - PullRequest
0 голосов
/ 25 мая 2020

Мы используем кварц для планирования заданий с 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']

Я предполагаю, что между проверкой существования и фактической вставкой другому узлу удается вставить строку для тот же идентификатор.

Так как я не очень люблю проверять сообщение в исключении на предмет чего-то вроде «Дублированная запись» и заглушать исключение с помощью уровня предупреждения в этом условии, я ищу другой решение, может быть, кварцевую конфигурацию?

1 Ответ

0 голосов
/ 13 июля 2020

Вы можете попробовать проверить, существует ли задание, перед тем как позвонить по номеру quartzServce.scheduleJob. Используя scheduler.checkExists(...)

Не уверен, что это то, что вы искали. Но похоже, что вам понадобится какая-то блокировка для этого идентификатора бизнес-объекта. Таким образом, только один узел пытается запланировать его. Вы можете сохранить идентификаторы отдельных объектов в таблице, прежде чем планировать для них задания. И позвольте вашим узлам захватить их с помощью блокировки, чтобы конкретный идентификатор объекта не был виден другим узлам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...