Java EJB ApplicationException: есть ли способ иметь дифференцированное поведение отката для перехваченных и неперехваченных исключений? - PullRequest
1 голос
/ 24 марта 2020

У меня проблема с перехваченным RuntimeException, помеченным как @ ApplicationException (rollback = true) откат моей транзакции базы данных и завершение транзакции для следующих действий.

@ApplicationException(rollback = true)
public class XyzValidationException extends RuntimeException {
   ...
}

process - это процесс пакетного импорта, который импортирует массовые данные кусками. Когда откат переносится, весь откат откатывается и после этого снова выбирается для импорта, поэтому все это повторяется в бесконечном l oop.

Сервер приложений - это JBoss 7.1, а база данных Oracle 11.2.

Я хочу перехватить исключение, пометить исходную сущность импорта как неисправную, записать что-либо и продолжить работу с остальными данными.

Но перехват исключения не предотвращает откат транзакции. Я прочитал об этом сейчас и понял, что это нормальное поведение. Но дело в том, как ты это делаешь тогда? Как настроить исключение, чтобы оно не откатывалось, когда оно было перехвачено, и все еще выполняло откат, когда оно не обработано? Я мог бы установить аннотацию исключений на @ApplicationException (rollback = false), но тогда я бы предотвратил откат в ситуации, когда исключение выбрасывается и не перехватывается, верно? В других процессах откат может быть разумным, когда выдается это исключение. Там я бы просто не хотел ловить ист. У кого-нибудь есть идеи, как мне этого добиться?

Я уже пытался изменить исключение на проверенное исключение (... расширяет исключение) и оставил аннотацию с rollback = true. Это не изменило поведение (я думал / надеялся, что откат = true, возможно, просто вступит в силу для необработанного исключения, и добьется цели в моем случае ... но нет) Затем я попробовал проверенное исключение с rollback = false, и, как и ожидалось, он добился цели. Но, как уже было описано, я не хочу полностью деактивировать откат ... только при обнаружении исключения. И, если возможно, я бы хотел придерживаться RuntimeException, поскольку у нас есть эта «Политика» для использования RuntimeExceptions везде, где это возможно, и необходимые объявления-броски будут распространяться по всему приложению ...

Спасибо за заранее ...

Фрэнк

1 Ответ

0 голосов
/ 29 марта 2020

У вас есть разные способы решения этой проблемы.

  1. Использовать исключения приложений. По умолчанию все отмеченные исключения являются исключениями приложения (кроме RemoteException). В модели CMT исключения такого рода не вызывают автоматического отката c. Таким образом, вы можете обработать возникшее исключение во время обработки чанка и сделать что-то такое, как log smth, без отката. В остальных случаях следует использовать непроверенные исключения, которые вызывают автоматический откат c.
  2. Если у вас есть некоторая «политика», придерживающаяся непроверенных исключений в вашем коде. Вы можете объявить исключение времени выполнения, например XyzValidationException, и добавить к нему примечание @ApplicationException(rollback = true), поэтому в случае, если оно выброшено, транзакция не будет откатываться. Для всего остального кода, где необходимо выполнить откат, вы можете использовать RuntimeException (по умолчанию rollback = false).
  3. Посмотрите на CDI, если это возможно в вашем проекте. Он предоставляет @ Transactional , который включает в себя такие свойства, как rollbackOn и dontRollbackOn.
...