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}))
aufmethod1
Versuchen 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
.
method2
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.