verschachtelt ist I-Code haben wie soVerhalten beim Frühling Propagation.REQUIRES_NEW in einem Propagation.NESTED
@Transactional(propagation = Propagation.NESTED)
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
public class C1 {
...
public void xxx() {
try {
obj.someMethod();
} catch (Exception e) {
C2.yyy();
}
}
}
public class C2 {
@Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = false)
public void yyy() {
...
}
}
Meine Vermutung ist, dass, wenn obj.someMethod();
eine Einschränkungsverletzung Ausnahme wirft C2.yyy()
noch in der Lage sein sollte, Sachen an die DB zu speichern .
aber was ich sehe, ist, dass, wenn C2.yyy()
genannt wird Postgres berichtet
ERROR: current transaction is aborted, commands ignored until end of transaction block
Warum sollte es das tun? Schließlich sollte C2.yyy()
in einer anderen Transaktion ausgeführt werden, die nicht durch den Status von dem, was in dem aufrufenden Code passiert, betroffen sein sollte. Nein?
aktualisieren
Bei der weiteren Fehlersuche hier ist, was ich gefunden - lassen Sie uns die Call-Stack sagen wie so ist
@Transactional(readOnly = false, propagation = Propagation.NESTED)
b1.m1()
@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
b2.m2()
b3.m3()
b4.m4()
Meine Vermutung war, dass der Code DB in m4() in einem neuen ausführen würde Transaktion wegen der Annotation auf b2.m2(). Aber es scheint, dass der Code in TransactionAspectSupport.java die Transaktionsannotation nur auf der aktuellen Methode und nicht auf dem Stapel betrachtet. Wenn es auf m4() kein @transactional findet, nimmt es REQUIRES an. Ist das nicht falsch?
Die "andere Abfrage" sollte jedoch in einer eigenen (neuen) Transaktion ausgeführt werden und sollte daher vom Status der zuvor ausgeführten Transaktion nicht betroffen sein. Ist das nicht eine Garantie dafür? – H1101
Gute Frage. Mein Verständnis ist, dass REQUIRES_NEW eine neue Verbindung verwendet, also haben Sie Recht, theoretisch sollte Ihr Code funktionieren ... Ich würde vorschlagen, die Protokollierung für 'org.springframework.transaction' zu aktivieren und Ihr Beispiel erneut auszuführen. Oder platzieren Sie einfach einen Breakpoint in AbstractPlatformTransactionManager.getTransaction (...) – Alexander
Verwenden Sie einfach JDBC, Hibernate oder etwas anderes? – Alexander