Я думаю, что мы должны дифференцировать
между «логическими» областями транзакций
и «физические» транзакции здесь ...
PROPAGATION_REQUIRED создает
объем логической транзакции для каждого
метод, к которому он применяется. каждый
такая логическая область транзакции может
индивидуально выбрать только откат
статус, с внешней транзакцией
сфера логически независима от
внутренняя область транзакции. из
конечно, в случае стандартного
PROPAGATION_REQUIRED поведение, они
будет сопоставлен с тем же физическим
сделка. Таким образом, маркер только для отката
установить во внутренней области транзакции
влияет на внешнюю транзакцию
шанс на самом деле совершить. Тем не мение,
поскольку объем внешней транзакции сделал
не решаться на сам откат
откат (молча срабатывает
внутренняя область транзакции)
неожиданно на этом уровне - что
почему UnexpectedRollbackException
получает бросок.
PROPAGATION_REQUIRES_NEW, напротив,
использует полностью независимый
транзакция для каждого пострадавшего
объем сделки. В этом случае
основные физические транзакции будут
быть разными и, следовательно, может совершить или
откат самостоятельно, с внешним
транзакция не затронута внутренним
статус отката транзакции.
PROPAGATION_NESTED снова отличается
в том, что он использует один физический
транзакция с несколькими точками сохранения
что он может откатиться к. Такой частичный
откаты позволяют внутреннюю транзакцию
объем, чтобы вызвать откат для его
сфера, с внешней транзакцией
возможность продолжить физическое
транзакция, несмотря на некоторые операции
откатился назад. Это
как правило, отображаются на точки сохранения JDBC,
так будет работать только с ресурсом JDBC
транзакции (весна
DataSourceTransactionManager).
Для завершения обсуждения:
Неожиданное исключение Rollback может также
быть брошенным без заявления когда-либо
установив маркер только для отката
сам. Вместо транзакции
инфраструктура, возможно, решила, что
единственный возможный результат
откат из-за ограничений в
текущее состояние транзакции. Это
особенно актуально с XA
сделки.
Как я и предлагал выше, бросая
исключение при внутренней транзакции
объем, а затем поймать это исключение в
внешняя сфера и перевод
в тихий вызов setRollbackOnly
там должно работать для вашего сценария.
вызывающая сторона внешней транзакции
никогда не вижу исключения тогда. С вами
беспокоиться только о таких тихих откатах
из-за особых требований
навязанный абонентом, я бы даже
утверждают, что правильный архитектурный
Решение состоит в том, чтобы использовать исключения в
уровень обслуживания, и переводить
эти исключения в бесшумные откаты
на уровне фасада сервиса (справа
прежде чем вернуться к этому специальному
вызывающий абонент).
Поскольку ваша проблема, возможно, не
только об исключениях отката, но
скорее о любых исключениях
с вашего уровня обслуживания, вы могли бы
даже использовать стандартные исключения на основе
Откаты на всем протяжении вас
уровень обслуживания, а затем поймать и войти
такие исключения после транзакции
уже завершено, в некоторых
приспосабливая сервисный фасад, который
переводит ваш уровень обслуживания
исключения в пользовательской ошибке
состояния.
Юрген