Вот моя проблема:
Я запускаю пакет в приложении Java EE/ Spring/Hibernate. Эта партия вызывает method1
. Этот метод вызывает method2
, который может бросать UserException
(класс, расширяющий RuntimeException
). Вот как это выглядит:
@Transactional
public class BatchService implements IBatchService {
@Transactional(propagation=Propagation.REQUIRES_NEW)
public User method2(User user) {
// Processing, which can throw a RuntimeException
}
public void method1() {
// ...
try {
this.method2(user);
} catch (UserException e) {
// ...
}
// ...
}
}
Исключением считается, что выполнение продолжается, но в конце method1
, когда транзакция закрыта, генерируется исключение RollbackException.
Вот трассировка стека:
org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:476)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy128.method1(Unknown Source)
at batch.BatchController.method1(BatchController.java:202)
Если method2
не выбрасывает это исключение, оно работает хорошо.
Что я пробовал:
- Настройка
@Transactional(noRollbackFor={UserException.class}))
наmethod1
- Попробуйте и поймайте
method2
Но это ничего не изменило.
Поскольку исключение выбрано в другой транзакции, где произошел откат, я не понимаю, почему он не работает. Я посмотрел на это: Jpa transaction javax.persistence.RollbackException: транзакция отмечена как rollbackOnly, но мне это действительно не помогло.
Я буду очень благодарен, если кто-то подскажет мне.
Обновление
Я сделал это, установив propagation=Propagation.REQUIRES_NEW
на метод, называемый method2
(который фактически является тем, который отправляет исключение). Этот метод определен в классе, очень похожем на my BatchService
. Поэтому я не понимаю, почему он работает на этом уровне, а не на method2
.
- Я установил
method2
как общедоступный, поскольку аннотация@Transactional
не учитывается, если метод является закрытым, как сказано в документации:
Аннотация @Transactional может быть помещена перед интерфейсом определение, метод на интерфейсе, определение класса или общедоступный метод в классе.
- Я также попытался использовать
Exception
вместоRuntimeException
(как это более подходит), но он ничего не изменил.
Даже если он работает, вопрос остается открытым, поскольку он имеет странное поведение, и я хотел бы понять, почему это не так, как должно быть.