Seltsames Verhalten bei @Transactional (Propagation = Propagation.REQUIRES_NEW)

Hier ist mein Problem:

Ich führe einen Stapel mit einer Java EE / Spring / Hibernate-Anwendung aus. Dieser Stapel ruft a aufmethod1. Diese Methode ruft a aufmethod2 was werfen kannUserException (Eine Klasse, die sich erweitertRuntimeException). So sieht es aus:

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

Die Ausnahme wird abgefangen, wenn die Ausführung fortgesetzt wird, jedoch am Ende vonmethod1 Beim Schließen der Transaktion wird eine RollbackException ausgelöst.

Hier ist der Stack-Trace:

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)

Wannmethod2 Wirft diese Ausnahme nicht, funktioniert es gut.

Was ich ausprobiert habe:

Rahmen@Transactional(noRollbackFor={UserException.class})) aufmethod1Versuchen Sie und fangen Sie anmethod2

Aber es hat sich nichts geändert.

Da die Ausnahme in einer anderen Transaktion ausgelöst wird, in der ein Rollback stattgefunden hat, verstehe ich nicht, warum dies nicht funktioniert. Ich habe mir das angeschaut:JPA-Transaktion javax.persistence.RollbackException: Transaktion als rollbackOnly markiert aber es hat mir nicht wirklich geholfen.

Ich wäre sehr dankbar, wenn mir jemand einen Hinweis geben könnte.

Aktualisieren

Ich habe es durch Einstellen zum Laufen gebrachtpropagation=Propagation.REQUIRES_NEW auf die von aufgerufene Methodemethod2 (Das ist eigentlich derjenige, der die Ausnahme sendet). Diese Methode ist in einer Klasse definiert, die meiner sehr ähnlich istBatchService. Ich verstehe also nicht, warum es auf dieser Ebene funktioniert und nicht aufmethod2.

Ich habe eingestelltmethod2 so öffentlich wie die Anmerkung@Transactional wird nicht berücksichtigt, wenn die Methode privat ist, wie in der Dokumentation angegeben:

Die @ Transactional-Annotation kann vor einer Schnittstellendefinition, einer Methode auf einer Schnittstelle, einer Klassendefinition oder einer öffentlichen Methode auf einer Klasse platziert werden.

Ich habe auch versucht, zu verwendenException anstattRuntimeException (wie es angemessener ist) aber es hat auch nichts geändert.

Auch wenn es funktioniert, bleibt die Frage offen, da es ein seltsames Verhalten hat und ich möchte verstehen, warum es sich nicht so verhält, wie es sein sollte.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage