Dziwne zachowanie w @Transactional (propagacja = Propagacja.REQUIRES_NEW)

Oto mój problem:

Używam partii na aplikacji Java EE / Spring / Hibernate. Ta partia wywołuje amethod1. Ta metoda wywołuje amethod2 które mogą rzucaćUserException (klasa rozszerzającaRuntimeException). Oto jak to wygląda:

@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) {
     // ...
   }
   // ...
 }
}

Wyjątek jest przechwytywany w miarę kontynuowania wykonywania, ale pod koniecmethod1 po zamknięciu transakcji rzucany jest wyjątek RollbackException.

Oto ślad stosu:

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)

Gdymethod2 nie rzuca tego wyjątku, działa dobrze.

Co próbowałem:

Oprawa@Transactional(noRollbackFor={UserException.class})) namethod1Spróbuj złapaćmethod2

Ale nic nie zmieniło.

Ponieważ wyjątek jest zgłaszany w innej transakcji, w której nastąpiło wycofanie, nie rozumiem, dlaczego nie działa. Spojrzałem na to:Jpa transaction javax.persistence.RollbackException: Transakcja oznaczona jako rollbackOnly ale to mi nie pomogło.

Będę bardzo wdzięczny, jeśli ktoś poda mi jakąś wskazówkę.

Aktualizacja

Zrobiłem to, ustawiającpropagation=Propagation.REQUIRES_NEW o metodzie zwanej przezmethod2 (w rzeczywistości to ten, który wysyła wyjątek). Ta metoda jest zdefiniowana w klasie bardzo podobnej do mojejBatchService. Więc nie rozumiem, dlaczego działa na tym poziomie, a nie namethod2.

Ustawiłemmethod2 tak publicznie jak adnotacja@Transactional nie jest brany pod uwagę, jeśli metoda jest prywatna, jak wspomniano w dokumentacji:

Adnotacja @Transactional może być umieszczona przed definicją interfejsu, metodą na interfejsie, definicją klasy lub metodą publiczną w klasie.

Próbowałem również użyćException zamiastRuntimeException (jak to jest bardziej odpowiednie), ale nic też nie zmieniło.

Nawet jeśli działa, pytanie pozostaje otwarte, ponieważ ma dziwne zachowanie i chciałbym zrozumieć, dlaczego nie działa tak, jak powinno.

questionAnswers(1)

yourAnswerToTheQuestion