JPA использует flu sh, чтобы вызвать исключение и остановить выполнение - PullRequest
0 голосов
/ 24 января 2020

В недавней задаче после создания объекта я сбросил результат в базу данных. Таблица базы данных имела уникальное ограничение, означающее, что если бы я попытался во второй раз отправить одну и ту же запись sh, я бы получил ConstraintViolationException. Пример фрагмента приведен ниже:

createEntityAndFlush(result);
sendAsyncRequestToThirdSystem(param);

Код для createEntityAndFlu sh:

private T createEntityAndFlush(final T entity) throws ServiceException {
    log.debug("Persisting {}", entity.getClass().getSimpleName());
    getEntityManager().persist(entity);
    getEntityManager().flush();
    return entity;
}

Причина, по которой я использовал flu sh, заключалась в том, что я хотел убедиться, что ConstraintViolationException будет выброшено до завершения транзакции и, следовательно, вызова sendAsyncRequestToThirdSystem. Но это был не тот случай, так как sendAsyncRequestToThirdSystem был вызван после исключения.

Чтобы проверить код в условиях гонки, я использовал ManagedExecutorService и создал две выполняемые задачи (Future<?> submit(Runnable task)) для репликации входящего запроса.

В конце концов проблема была решена попыткой выполнить блокировку новой таблицы для каждого уникального идентификатора запроса, но я хотел бы знать, в чем я ошибался при первом подходе (например, неправильное использование fla sh , ManagedExecutorService был ответственным за неловкое поведение). Заранее спасибо!

1 Ответ

2 голосов
/ 24 января 2020

Проблема заключается в том, что хотя flush() делает грипп sh изменения в базе данных, транзакция все еще открыта, и уникальное ограничение будет проверяться, когда транзакция зафиксирована (это может зависеть в базе данных, но, по крайней мере, с Postgres и любым MV CC с использованием БД).

Поэтому вам необходимо убедиться, что createEntityAndFlush(result); выполняется в своей собственной транзакции, возможно с @Transactional(propagation = Propagation.REQUIRES_NEW) (или эквивалентным, если не используется Spring), чтобы увидеть, нарушен ли уникальный индекс.

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