1. Grundprinzipien von Transaktionen
Die Essenz von Frühlingstransaktionen ist tatsächlich die Unterstützung der Datenbank für Transaktionen. Ohne Datenbank -Transaktionsunterstützung kann Spring keine Transaktionsfunktionen bereitstellen. Wenn Sie für reine JDBC -Betriebsdatenbanken Transaktionen verwenden möchten, können Sie die folgenden Schritte ausführen:
1. Holen Sie sich die Verbindungsverbindung con = driverManager.getConnection ()
2. Öffnen Sie die Transaktion con.setAutocommit (true/false);
3. Führen Sie Crud aus
4. Commit Transaction / Rollback Transaction con.commit () / con.rollback ();
5. Schließen Sie die Verbindung conn.close ();
Nachdem wir die Transaktionsmanagementfunktion von Spring verwendet haben, können wir den Code in den Schritten 2 und 4 nicht mehr schreiben, sondern automatisch von Spirng durchgeführt. Wie öffnen und schließen Spring Transaktionen vor und nach dem Crud, den wir schreiben? Durch die Lösung dieses Problems können wir das Implementierungsprinzip des Transaktionsmanagements von Spring aus einem Ganzen verstehen. Lassen Sie mich kurz die Annotationsmethode als Beispiel vorstellen
1. Schalten Sie den Annotationstreiber in der Konfigurationsdatei ein und identifizieren Sie ihn, indem Sie den @Transactional für die relevanten Klassen und Methoden annotieren.
2. Wenn der Frühling beginnt, analysiert und erzeugt es verwandte Bohnen. Zu diesem Zeitpunkt werden die Klassen und Methoden mit relevanten Anmerkungen überprüft und einen Proxy für diese Klassen und Methoden generiert und die verwandte Konfigurationseinspritzung basierend auf den relevanten Parametern von @Transaction durchgeführt, sodass die relevanten Transaktionen für uns im Proxy verarbeitet werden (Start -Normal -Transaktionen und Ausnahmeregelungstransaktionen).
3.. Transaktionsausschüsse und Rollback der realen Datenbankschicht werden über Binlog oder Redo -Protokoll implementiert.
2. Propagationseigenschaften von Federtransaktionen
Das sogenannte Ausbreitungsattribut von Federtransaktionen definiert, wie der Feder mit dem Verhalten mehrerer Transaktionen umgehen sollte, wenn sie gleichzeitig existieren. Diese Eigenschaften sind in der Transaktionsdefinition definiert. Die spezifischen Konstanten werden in der folgenden Tabelle erklärt:
III. Datenbankisolationsstufe
Dirty Lesen: Eine Transaktion fügt die Daten hinzu, löscht und modifiziert, wird jedoch nicht verpflichtet, und eine andere Transaktion kann nicht übereinstimmende Daten lesen. Wenn die erste Transaktion zu diesem Zeitpunkt zurückrollt, liest die zweite Transaktion schmutzige Daten.
Keine sich wiederholende Lektüre: Zwei Lesevorgänge treten in einer Transaktion auf. Zwischen dem ersten Lesevorgang und dem zweiten Betrieb modifiziert die andere Transaktion die Daten. Zu diesem Zeitpunkt sind die zweimal gelesenen Daten inkonsistent.
Fantasy -Lesen: Die erste Transaktion verändert die Daten in einem bestimmten Bereich in Stapeln, und die zweite Transaktion fügt diesem Bereich eine Daten hinzu. Zu diesem Zeitpunkt verliert die erste Transaktion die Änderung der neu hinzugefügten Daten.
Zusammenfassen :
Je höher die Isolationsstufe, desto mehr kann es die Integrität und Konsistenz der Daten gewährleisten, aber desto größer ist die Auswirkungen auf die Gleichzeitleistung.
Die Standard -Isolationsstufe der meisten Datenbanken wird in Auftrag gegeben, wie SQLServer und Oracle
Die Standard -Isolationsstufe einiger Datenbanken lautet: Wiederholbares Lesen zum Beispiel: MySQL InnoDB
Iv. Isolationsniveau im Frühjahr
V. Verschachteln von Transaktionen
Durch das obige theoretische Wissen verstehen wir einige Attribute und Eigenschaften von Datenbanktransaktionen und Federtransaktionen grob. Als nächstes analysieren wir einige verschachtelte Transaktionsszenarien, um den Mechanismus der Federtransaktionsausbreitung tief zu verstehen.
Angenommen, die Methode a () des äußeren Transaktionsdienstes A ruft die Methode B () des inneren Dienstes B auf
Propagation_Required (Spring Standard)
Wenn das Transaktionsniveau von ServiceB.Methodb () als Propagation_Requeur definiert ist, ist die Transaktion bereits im Frühjahr begonnen, wenn die servicea.methoda () ausgeführt wird. Zu diesem Zeitpunkt wird ServiceB.Methodb () aufgerufen. ServiceB.Methodb () sieht, dass es in der Transaktion von servicea.methoda () läuft und keine neue Transaktion gestartet wird.
Wenn serviceB.Methodb () ausgeführt wird, wird sich selbst eine Transaktion zugewiesen.
Auf diese Weise wird die Transaktion zurückgerollt, wenn eine Ausnahme in servicea.methoda () oder überall in serviceB.Methodb () auftritt.
Propagation_Requires_New
Zum Beispiel haben wir so konzipiert, dass servicea.methoda () ein Transaktionsniveau von Propagation_Required hat, und ServiceB.Methodb () über ein Transaktionsniveau der Propagation_Requires_New.
Wenn dann der ServiceB.Methodb () ausgeführt wird, wird die Transaktion, in der servicea.methoda () lokalisiert wird, ausgesetzt, und ServiceB.Methodb () startet eine neue Transaktion und wird weiterhin ausgeführt, nachdem der ServiceB.Methodb () Transaktion abgeschlossen ist.
Der Unterschied zwischen seinen Transaktionen und seiner Ausbreitung ist der Rollback der Transaktion. Da ServiceB.Methodb () eine neue Transaktion ist, gibt es zwei verschiedene Transaktionen. Wenn serviceB.Methodb () eingereicht wurde, wird servicea.methoda () nicht rollback, ServiceB.Methodb () nicht rollback. Wenn ServiceB.Methodb () nicht zurückrollt, kann die Servicea -Transaktion weiterhin eingereicht werden.
Ausbreitung_Supports
Unter der Annahme, dass das Transaktionsniveau von ServiceB.Methodb () Propagation_Supports ist, wenn sie in serviceB.Methodb () ausgeführt wird, wird es bei der aktuellen Transaktion verbunden, dass servicea.methoda () eine Transaktion geöffnet hat. Wenn festgestellt wird, dass servicea.methoda () die Transaktion nicht begonnen hat, wird die Transaktion nicht selbst gestartet. Zu diesem Zeitpunkt hängt die Transaktionalität der internen Methode vollständig von der äußersten Transaktion ab.
Propagation_Nested
Die Situation wird jetzt komplizierter. Die Transaktionseigenschaft von ServiceB.MethodB () ist als Propagation_nested konfiguriert. Wie werden die beiden zu dieser Zeit zusammenarbeiten? ServiceB#methodb if Rollback, dann interne Transaktionen (d. H. ServiceB#methodb) zurück zu SavePoint zurück, bevor sie ausgeführt werden, während externe Transaktionen (d. H. Servicea#methoda) die folgenden zwei Möglichkeiten zur Handhabung haben können:
A. Fangen Sie Ausnahmen an und führen Sie die Ausnahmebietslogik aus
void methoda () {try {serviceB.Methodb (); } catch (einigexception) {// andere Unternehmen ausführen, wie z. B. servicec.methodc (); }} Diese Methode ist auch das wertvollste an verschachtelten Transaktionen. Es spielt die Rolle der Zweigausführung. Wenn ServiceB.MethodB fehlschlägt, wird servicec.methodc () ausgeführt, und ServiceB.Methodb hat vor der Ausführung keine schmutzigen Daten generiert (entspricht dieser Methode, die niemals ausgeführt wird). Diese Funktion kann in einigen speziellen Diensten verwendet werden, und weder Propagation_required noch propagation_requires_new können dies tun.
B. Der externe Transaktionsrollback/Commit -Code enthält keine Änderungen. Wenn der Rollback der internen Transaktion (serviceB#methodb), rollt er First ServiceB.MethodB zurück zum SavePoint, bevor er (auf jeden Fall) ausführt, und die externe Transaktion (d. H. Servicea#methoda) entscheidet, ob sie basierend auf der spezifischen Konfiguration eingehen oder Rollback basiert.
Die anderen drei Transaktionsausbreitungsattribute sind grundsätzlich unwirksam, so dass hier keine Analyse durchgeführt wird.
6. Zusammenfassung
Für Orte, an denen Transaktionen im Projekt benötigt werden, schlage ich vor, dass Entwickler die TransactionCallback -Schnittstelle von Spring verwenden sollten, um Transaktionen zu implementieren. Verwenden Sie keine blindenden Anmerkungen der Feder -Transaktion. Wenn Sie Anmerkungen verwenden müssen, müssen Sie ein detailliertes Verständnis des Ausbreitungsmechanismus und des Isolationsniveaus von Federtransaktionen haben, ansonsten können unerwartete Effekte auftreten.