Gewusst wie: Rollback zu Savepoint geschachtelten Transaktionen mit Hibernate

8

Ich habe eine JavaEE-Anwendung, die Hibernate verwendet, um eine Verbindung zur Datenbank herzustellen. In einem Teil meiner Anwendung habe ich Aufrufe an Methoden, die eine @Transactional Annotation haben. In einigen dieser Fälle möchte ich die gesamte Transaktion (den Outer-Service-Methodenaufruf und den inneren) zurücksetzen. Und in einigen Fällen möchte ich nur den Aufruf der inneren Service-Methode zurücksetzen (dh Rollback auf den Sicherungspunkt , der zu Beginn der internen Methode definiert wurde).

Der erste Teil ist bereits vorhanden, aber ich habe ein Problem mit dem zweiten. Wenn ich Folgendes tue, erhalte ich eine "UnexpectedRollbackException" mit der Meldung "Transaktion wurde zurückgesetzt, da sie als Rollback-Only markiert wurde".

%Vor%     
hfm 25.11.2013, 16:58
quelle

3 Antworten

6

Die Funktion, nach der Sie suchen, heißt Sicherungspunkte . Sie sind nicht streng geschachtelte Transaktionen, sondern Meilensteine ​​in der konsequenten SQL-Befehlskette, auf die Sie zurückrollen können. Beim Zurücksetzen auf Savepoint werden ALLE Anweisungen ungültig, die ab dem Zeitpunkt der Erstellung des Sicherungspunkts ausgegeben werden. Sie können also mehrere Sicherungspunkte haben. Sie können jedoch nur Anweisungen zwischen jetzt und Sicherungspunkt zurückrollen zwischen 2 Sicherungspunkten!

Spring unterstützt Savepoints, wenn Sie JdbcTransactionObjectSupport manuell und mit @Transactional Annotation.

Laut dem Dokument Ссылка zeigen Sie 9.5.7.3 Sie sollten Propagation.NESTED verwenden.

Diese Optionen sind in Ihrem Fall jedoch möglicherweise nicht verfügbar. Von Javadoc:

  

Hinweis: Die eigentliche Erstellung einer verschachtelten Transaktion funktioniert nur   bestimmte Transaktionsmanager. Out of the Box gilt dies nur für   der JDBC DataSourceTransactionManager bei der Arbeit an einem JDBC 3.0   Treiber. Einige JTA-Anbieter unterstützen möglicherweise auch geschachtelte Transaktionen.

Als letzten Ausweg können Sie SQL-Anweisungen ausführen, die direkt zu Savepoint starten / Rollback ausführen.

Für PostgreSQL wäre es:

%Vor%

Quelle: Ссылка

    
Danubian Sailor 11.02.2014 13:00
quelle
0

Es gibt keine Unterstützung für verschachtelte Transaktionen in Spring / Hibernate / Java EE. Entweder wird das Ganze rückgängig gemacht oder die innere Transaktion ist eine neue, andere Transaktion, die ausgeführt wird, sobald sie erfolgreich ist, und selbst wenn die äußere Transaktion später rückgängig gemacht wird.

Wenn letzteres das ist, was Sie wollen, dann notieren Sie einfach Ihre innere Methode mit

%Vor%     
JB Nizet 25.11.2013 17:27
quelle
0

Versuchen Sie, das Attribut globalRollbackOnParticipationFailure Ihres TransactionManager auf false zu setzen.

Siehe Ссылка für weitere Informationen.

    
nayv 11.02.2014 09:16
quelle