JPA concurrency issue "При выпуске пакета все еще содержатся заявления JDBC"

У меня есть проблема с concurrency, которую я пытался решить с помощью цикла while, который пытается сохранить объект несколько раз, пока он не достигнет максимального количества попыток повтора. Я бы хотел не говорить о том, есть ли другие способы решения этой проблемы. У меня есть другие сообщения Stackoverflow.:) Короче говоря: существует уникальное ограничение на вывод столбца и включает числовую часть, которая продолжает увеличиваться, чтобы избежать столкновений. В цикле I:

  • выберите max (some_value)
  • увеличить результат
  • попытка сохранить новый объект с этим новым результатом
  • явно очистить объект и, если это не удается из-за уникального индекса, я поймаю исключение DataAccessException.

Все это, похоже, работает, за исключением случаев, когда цикл возвращается к шагу 1 и пытается выбрать, я получаю:

17:20:46,111 INFO  [org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl] (http-localhost/127.0.0.1:8080-3) HHH000010: On release of batch it still contained JDBC statements
17:20:46,111 INFO  [my.Class] (http-localhost/127.0.0.1:8080-3) MESSAGE="Failed to save to database. Will retry (retry count now at: 9) Exception: could not execute statement; SQL [n/a]; constraint [SCHEMA_NAME.UNIQUE_CONSTRAINT_NAME]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement"

И новое Исключение поймано. Кажется, что первый флеш, который вызывает уникальное нарушение ограничений, и выбрасывает DataAccessException, не очищает пакет управления сущностью. Каким образом можно справиться с этим? Я использую Spring с JPA и не имею прямого доступа к диспетчеру сущности. Думаю, я мог бы впрыснуть, если понадобится, но это болезненное решение этой проблемы.

Ответ 1

Вы не можете этого сделать - как только вы что-то смываете, и он терпит неудачу, и генерируется исключение, транзакция будет отмечена как откат. Это означает, что не имеет значения, что вы поймаете исключение и продолжаете, вы получите откат. На самом деле вообще не имеет значения, какое исключение было выбрано - по умолчанию Spring диспетчер транзакций откатывается при каждом неконтролированном исключении. Вы можете преодолеть это путем специфического определения noRollbackFor в аннотации @Transactional (при условии, что вы используете транзакции драйвера аннотаций)

Изменить - это также не поможет вам в случае нарушения этого ограничения, поскольку транзакция будет, вероятно, отмечена как откат на уровне базы данных.

Ответ 2

Я нашел этот вопрос, получая ту же ошибку. В моем случае проблема была вызвана странной комбинацией блокировки триггера и строки (см. Исключение PSQLEx и блокировка при добавлении триггера в таблицу). Однако потребовалось некоторое время, чтобы обнаружить, что эта ошибка является лишь следствием первичной ошибки, а не причиной. Когда Hibernate сбрасывает сессию и происходит некоторое ограничение, он получает исключение JDBC и в блоке finally пытается вызвать abortBatch. Когда какой-либо оператор остается в сеансе, Hibernate выдает это предупреждение, хотя фактическую ошибку следует искать где-то раньше.