Heim  >  Artikel  >  Java  >  So lösen Sie das Problem der verteilten Java Spring Boot-Transaktionen

So lösen Sie das Problem der verteilten Java Spring Boot-Transaktionen

PHPz
PHPznach vorne
2023-04-18 12:34:021477Durchsuche

1. Was ist Reverse Compensation? Lassen Sie mich zunächst einen Begriff erklären. Wenn Sie sich Informationen zu verteilten Transaktionen ansehen, werden Sie häufig auf einen Begriff stoßen:

Reverse Compensation. Was ist eine umgekehrte Kompensation?

Lassen Sie mich ein Beispiel geben: Angenommen, wir haben jetzt drei Microservices, nämlich A, B und C. Jetzt rufen wir die Dienste B und C jeweils in Dienst A auf. Um sicherzustellen, dass B und C gleichzeitig erfolgreich sind oder scheitern Zeit müssen wir die Verteilung formaler Angelegenheiten nutzen. Nach unserem bisherigen Verständnis lokaler Transaktionen tritt jedoch bei lokalen Transaktionen in B und C nach Abschluss und Übermittlung der Transaktion in Dienst B eine Ausnahme in der Transaktion in Dienst C auf, die jedoch zurückgesetzt werden muss eingereicht. Wie kann ich ein Rollback durchführen?

Bei dem Rollback, über das wir derzeit sprechen, handelt es sich eigentlich nicht um das traditionelle Rollback über das MySQL-Redo-Log,

sondern um die Verwendung eines Update-SQL, um die geänderten Daten in Dienst B wiederherzustellen.

Das nennen wir Reverse Compensation!

2. Grundlegende Konzeptüberprüfung

Es gibt drei Kernkonzepte in Seata:

TC (Transaktionskoordinator) – Transaktionskoordinator: verwaltet den Status globaler Transaktionen und Filialtransaktionen und steuert die globale Transaktionsübermittlung oder das Rollback.
  • TM (Transaktionsmanager) – Transaktionsmanager: Definieren Sie den Umfang globaler Transaktionen, starten Sie globale Transaktionen, übernehmen Sie globale Transaktionen oder setzen Sie sie zurück.
  • RM (Ressourcenmanager) – Ressourcenmanager: verwaltet die Ressourcen (Ressource) für die Verarbeitung von Filialtransaktionen, kommuniziert mit TC, um Filialtransaktionen zu registrieren und den Status von Filialtransaktionen zu melden, und steuert die Festschreibung oder das Rollback von Filialtransaktionen.
  • Dabei ist TC ein separat bereitgestellter Server und TM und RM sind in die Anwendung eingebettete Clients.

Schauen wir uns das folgende Bild an:

Dieses Bild erklärt im Grunde diese drei Konzepte klar. So lösen Sie das Problem der verteilten Java Spring Boot-Transaktionen

Ohne dieses Bild zu betrachten, können wir wahrscheinlich das Implementierungsprinzip verteilter Transaktionen erraten: Zuerst muss es einen globalen Transaktionskoordinator (TC) geben, und jede lokale Transaktion (RM) beginnt mit der Ausführung oder während der Ausführung Sobald er (TC) feststellt, dass alle lokalen Transaktionen erfolgreich ausgeführt wurden, benachrichtigt er den globalen Transaktionskoordinator rechtzeitig Wenn er feststellt, dass jemand diese Transaktion nicht ausgeführt hat, benachrichtigt er alle, gemeinsam einen Rollback durchzuführen (dieser Rollback ist natürlich nicht unbedingt ein echter Rollback, sondern eine umgekehrte Kompensation). Wann beginnt und endet eine Transaktion? Das heißt, wo liegen die Grenzen der Transaktion? Verteilte Transaktionen in Seata werden alle durch

-Anmerkungen implementiert. Mit anderen Worten: Wo sollte diese Anmerkung hinzugefügt werden? Der Ort zum Hinzufügen dieser Anmerkung ist eigentlich das Transaktionsmanager-TM.

Nach der obigen Einführung sollten Freunde verstehen, dass die Verwendung von Seata zur Implementierung verteilter Transaktionen nicht so schwierig ist wie gedacht und das Prinzip immer noch sehr einfach ist. @GlobalTransactional

Seata umfasst vier verschiedene Modi. Bei den vier als nächstes vorgestellten verschiedenen Modi geht es tatsächlich darum, wie ein Rollback durchgeführt werden kann, wenn eine lokale Transaktion fehlschlägt. Dies sind die vier verschiedenen verteilten Transaktionsmodi, über die wir später sprechen werden.

3. Was ist eine zweistufige Einreichung? Schauen Sie sich zunächst das Bild unten an:

Dieses Bild beinhaltet drei Konzepte:

So lösen Sie das Problem der verteilten Java Spring Boot-Transaktionen

AP: Es versteht sich von selbst, der AP ist die Anwendung selbst.

  • RM: RM ist der Ressourcenmanager, der an der Transaktion beteiligt ist. In den meisten Fällen handelt es sich um eine verteilte Transaktion, an der mehrere RMs beteiligt sind.

  • TM: TM ist der Transaktionsmanager, der verteilte Transaktionen erstellt und die Ausführung und den Status jeder Untertransaktion in der verteilten Transaktion koordiniert. Untertransaktionen beziehen sich auf bestimmte auf RM ausgeführte Vorgänge.

  • Was ist also Two-Phase Commit (kurz 2PC)? Die Wahrheit der zweistufigen Einreichung ist sehr einfach. Brother Song gibt Ihnen ein einfaches Beispiel, um die zweistufige Einreichung zu erklären:

Zum Beispiel das folgende Bild:

Wir nennen Lagerung und Ordnung Im Geschäftskonto müssen die Vorgänge in diesen drei Diensten gleichzeitig erfolgreich sein oder fehlschlagen. Da sich diese drei jedoch in unterschiedlichen Diensten befinden, können wir die Vorgänge in diesen drei Diensten nur separat ausführen lassen separat. Die erste von zwei Stufen.

Nachdem die erste Phase der Ausführung abgeschlossen ist, beeilen Sie sich nicht mit der Übermittlung, da einige der drei Dienste möglicherweise nicht ausgeführt wurden. Zu diesem Zeitpunkt müssen die drei Dienste die Ausführungsergebnisse ihrer ersten Phase einem Transaktionskoordinator melden . Wenn die erste Phase der drei Dienste erfolgreich ausgeführt wurde, wird der Transaktionskoordinator den drei Transaktionen zur Übermittlung mitgeteilt. Wenn einer der drei Dienste fehlschlägt, werden die drei Transaktionen zum Zurücksetzen aufgefordert jeweils.

Dies wird als zweiphasiges Commit bezeichnet.

Um es zusammenzufassen: Bei der zweistufigen Übermittlung wird die Transaktion in Teilnehmer unterteilt (z. B. jeder spezifische Dienst im Bild oben) und der Koordinator. Die Teilnehmer benachrichtigen den Koordinator über den Erfolg oder Misserfolg des Vorgangs und dann Der Koordinator trifft Entscheidungen auf der Grundlage der Feedbackinformationen aller Teilnehmer. Unabhängig davon, ob der Teilnehmer den Vorgang einreichen oder abbrechen möchte, kann der Teilnehmer hier als RM und der Koordinator als TM verstanden werden.

Die verschiedenen verteilten Transaktionsmodi in Seata basieren jedoch grundsätzlich auf der Grundlage der zweistufigen Übermittlung und sind daher nicht genau gleich. Dies muss von Freunden beachtet werden.

4. Der AT-Modus ist ein vollautomatischer Transaktions-Rollback-Modus.

Insgesamt ist der AT-Modus eine Weiterentwicklung des zweiphasigen Festschreibungsprotokolls:

    Einphasig: Geschäftsdaten und Rollback-Protokolldatensätze werden in derselben lokalen Transaktion festgeschrieben, wodurch lokale Sperren und Verbindungsressourcen freigegeben werden.
  • Die zweite Phase ist in zwei Situationen unterteilt: 2.1 Asynchrones Senden, was sehr schnell abgeschlossen ist. 2.2 Rollback führt eine umgekehrte Kompensation durch ein einstufiges Rollback-Protokoll durch.
  • Die allgemeine Logik ist wie oben. Schauen wir uns an, wie der AT-Modus in einem bestimmten Fall funktioniert:

Angenommen, es gibt ein Business-Tischprodukt wie folgt:

So lösen Sie das Problem der verteilten Java Spring Boot-Transaktionen

Jetzt wollen wir es tun Der folgende Aktualisierungsvorgang:

update product set name = 'GTS' where name = 'TXC';

Die Schritte sind wie folgt:

Phase eins:

    SQL analysieren: SQL-Typ (UPDATE), Tabelle (Produkt), Bedingung (wobei Name = ') abrufen TXC') und andere verwandte Informationen.
  • Bild vor der Abfrage: Generieren Sie basierend auf den durch Parsen erhaltenen bedingten Informationen Abfrageanweisungen und suchen Sie Daten (finden Sie Daten vor der Aktualisierung).
  • Führen Sie die obige Update-SQL aus.
  • Fragen Sie den Nachspiegel ab: Suchen Sie die Daten basierend auf den Ergebnissen des Vorspiegels über den
  • Primärschlüssel

    .

  • Rollback-Protokoll einfügen: Kombinieren Sie die Vor- und Nachher-Spiegeldaten und Geschäfts-SQL-bezogenen Informationen in einem Rollback-Protokolldatensatz und fügen Sie ihn in die UNDO_LOG-Tabelle ein.
  • Registrieren Sie vor dem Absenden die Filiale bei TC: Beantragen Sie eine globale Sperre für den Datensatz mit dem Primärschlüsselwert gleich 1 in der Produkttabelle.
  • Lokale Transaktionsübermittlung: Die Aktualisierung der Geschäftsdaten wird zusammen mit dem im vorherigen Schritt generierten UNDO-LOG übermittelt.
  • Melden Sie die Ergebnisse der lokalen Transaktionseinreichung an TC.
Zweite Phase:

Die zweite Phase ist in zwei Situationen unterteilt: Commit oder Rollback.

Sehen wir uns zunächst die Rollback-Schritte an:

    Erhalten Sie zunächst die Zweig-Rollback-Anfrage von TC, starten Sie eine lokale Transaktion und führen Sie die folgenden Vorgänge aus.
  • Suchen Sie den entsprechenden UNDO LOG-Datensatz über XID und Filial-ID (in diesem Datensatz werden die entsprechenden Bilder vor und nach der Datenänderung gespeichert).
  • Datenüberprüfung: Vergleichen Sie das Post-Bild im UNDO LOG mit den aktuellen Daten. Wenn es einen Unterschied gibt, bedeutet dies, dass die Daten durch andere Aktionen als die aktuelle globale Transaktion geändert wurden. Diese Situation muss gemäß der Konfigurationsrichtlinie behandelt werden.
  • Rollback-Anweisungen generieren und ausführen, basierend auf den relevanten Informationen des vorherigen Bildes und Business SQL im UNDO LOG: update product set name = 'TXC' where id = 1;
  • update product set name = 'TXC' where id = 1;

  • 提交本地事务。并把本地事务的执行结果(即分支事务回滚的结果)上报给 TC。

再来看提交步骤:

  • 收到 TC 的分支提交请求,把请求放入一个异步任务的队列中,马上返回提交成功的结果给 TC。

  • 异步任务阶段的分支提交请求将异步和批量地删除相应 UNDO LOG 记录。

大致上就是这样一个步骤,思路还是比较清晰的,就是当你要更新一条记录的时候,系统将这条记录更新之前和更新之后的内容生成一段 JSON 并存入 undo log 表中,将来要回滚的话,就根据 undo log 中的记录去更新数据(反向补偿),将来要是不回滚的话,就删除 undo log 中的记录。

在整个过程中,开发者只需要额外创建一张 undo log 表就行了,然后给需要处理全局事务的地方加上 @GlobalTransactional

Submit Lokale Angelegenheiten. Und melden Sie das Ausführungsergebnis der lokalen Transaktion (dh das Ergebnis des Rollbacks der Zweigstellentransaktion) an TC.

Schauen wir uns noch einmal die Übermittlungsschritte an:

empfängt die Zweig-Übermittlungsanfrage von TC, stellt die Anforderung in eine asynchrone Aufgabenwarteschlange und gibt das erfolgreiche Übermittlungsergebnis sofort an TC zurück.

So lösen Sie das Problem der verteilten Java Spring Boot-Transaktionen

Branch-Übermittlungsanfragen in der asynchronen Aufgabenphase löschen die entsprechenden UNDO-LOG-Datensätze asynchron und stapelweise.

🎜🎜🎜Es ist im Grunde ein solcher Schritt. Wenn Sie einen Datensatz aktualisieren möchten, generiert das System einen JSON für den Inhalt vor und nach der Aktualisierung des Datensatzes und speichert ihn in der Undo-Log-Tabelle Sie möchten in Zukunft ein Rollback durchführen, aktualisieren Sie die Daten basierend auf den Datensätzen im Rückgängig-Protokoll (umgekehrte Kompensation). Wenn Sie in Zukunft kein Rollback durchführen möchten, löschen Sie die Datensätze im Rückgängig-Protokoll. 🎜🎜Im gesamten Prozess müssen Entwickler lediglich eine zusätzliche Rückgängig-Protokolltabelle erstellen und dann @GlobalTransactional-Anmerkungen hinzufügen, wo globale Transaktionen verarbeitet werden müssen. 🎜🎜Andere Übermittlungen, Rollbacks und Rollbacks erfolgen alle vollautomatisch, was einfacher ist. Wenn Sie sich also für die Verwendung von Seata zur Abwicklung verteilter Transaktionen in Ihrem Projekt entscheiden, ist die Wahrscheinlichkeit, den AT-Modus zu verwenden, immer noch recht hoch. 🎜🎜5. Der TCC-Modus (Try-Confirm-Cancel) hat ein gewisses Maß an manuellem Charakter. Er ist ebenfalls zweistufig, unterscheidet sich jedoch vom AT. 🎜🎜🎜Auf der offiziellen Website gibt es ein Flussdiagramm von TCC. Werfen wir einen Blick darauf: 🎜🎜🎜🎜🎜🎜Wie Sie sehen können, ist TCC ebenfalls in zwei Phasen unterteilt: 🎜
  • Die erste Phase ist die Vorbereitung. In dieser Phase werden hauptsächlich Ressourcen wie Banküberweisungen erkannt und reserviert. In dieser Phase prüfen wir zunächst, ob das Geld des Benutzers ausreicht Wenn es ausreicht, wird es zuerst eingefroren.

  • Die zweite Stufe ist das Festschreiben oder Zurücksetzen. Dabei wird hauptsächlich darauf gewartet, dass die erste Stufe jeder Zweigtransaktion abgeschlossen ist. Nach Abschluss aller Ausführungen meldet TC seine eigene Situation Wenn TC feststellt, dass eine Filialtransaktion abnormal ist, benachrichtigen Sie alle zum Zurücksetzen.

Dann haben Ihre Freunde vielleicht herausgefunden, dass der obige Prozess insgesamt drei Methoden umfasst: Vorbereiten, Festschreiben und Zurücksetzen. Diese drei Methoden sind vollständig benutzerdefinierte Methoden und wir müssen sie selbst implementieren Der Anfang, dass TCC ein manueller Modus ist.

Im Vergleich zu AT haben alle festgestellt, dass der TCC-Modus tatsächlich nicht von der Transaktionsunterstützung der zugrunde liegenden Datenbank abhängt. Mit anderen Worten, es spielt keine Rolle, auch wenn Ihre zugrunde liegende Datenbank keine Transaktionen unterstützt Vorbereiten, Festschreiben und Zurücksetzen sind Die Entwickler haben es selbst geschrieben, und wir müssen nur die Prozesse glätten, die diesen drei Methoden entsprechen.

6. XA-Modus

Wenn Sie die XA-Transaktionen der MySQL-Datenbank verstehen, werden Sie verstehen, worum es beim XA-Modus in Seata geht.

Die XA-Spezifikation ist ein DTP-Standard (Distributed Transaction Processing), der von der X/Open-Organisation definiert wird.

Die XA-Spezifikation beschreibt die Schnittstelle zwischen dem globalen Transaktionsmanager und dem lokalen Ressourcenmanager. Der Zweck der XA-Spezifikation besteht darin, den Zugriff auf mehrere Ressourcen (z. B. Datenbanken, Anwendungsserver, Nachrichtenwarteschlangen usw.) in derselben Transaktion zu ermöglichen, sodass die ACID-Eigenschaften anwendungsübergreifend gültig bleiben.

Die XA-Spezifikation verwendet zweiphasiges Commit, um sicherzustellen, dass alle Ressourcen gleichzeitig eine bestimmte Transaktion festschreiben oder zurücksetzen.

Die XA-Spezifikation wurde Anfang der 1990er Jahre vorgeschlagen. Derzeit unterstützen fast alle Mainstream-Datenbanken die XA-Spezifikation.

XA-Transaktionen basieren auf dem zweiphasigen Commit-Protokoll. Um sicherzustellen, dass alle Transaktionsteilnehmer die Vorbereitungsarbeiten (erste Phase) abgeschlossen haben, ist ein Transaktionskoordinator erforderlich. Wenn der Koordinator eine Nachricht erhält, dass alle Teilnehmer bereit sind, benachrichtigt er ihn darüber, dass alle Transaktionen festgeschrieben werden können (Phase 2). MySQL spielt bei dieser XA-Transaktion die Rolle eines Teilnehmers, nicht des Koordinators (Transaktionsmanagers).

Die XA-Transaktionen von MySQL sind in internes XA und externes XA unterteilt. Externes Commit muss sein Die Informationen werden in das Binärprotokoll geschrieben, bei dem es sich um eine verteilte interne XA-Transaktion handelt, mit der Ausnahme, dass der Teilnehmer am Binärprotokoll MySQL selbst ist. MySQL spielt bei XA-Transaktionen die Rolle eines Teilnehmers, nicht eines Koordinators.

Mit anderen Worten: MySQL kann verteilte Transaktionen natürlich über die XA-Spezifikation implementieren, benötigt jedoch nur die Unterstützung einiger externer Anwendungen. Werfen wir einen Blick auf den Nutzungsprozess des XA-Modus in Seata.

Erster Blick auf ein offizielles Bild:

So lösen Sie das Problem der verteilten Java Spring Boot-Transaktionen

Wie Sie sehen, handelt es sich auch hier um eine zweistufige Einreichung:

  • Phase 1: Business SQL-Operationen werden im XA-Zweig, XA, durchgeführt Nach Abschluss der Verzweigung wird die XA-Vorbereitung ausgeführt und die Persistenz wird durch die Unterstützung des XA-Protokolls durch RM gewährleistet (d. h. nachfolgende Unfälle führen nicht zu einem Rollback-Fehler).

  • Die zweite Phase ist in zwei Situationen unterteilt: Commit oder Rollback:

  • Branch-Commit: Führen Sie das Commit des XA-Zweigs aus.

  • Branch-Rollback: Führen Sie das Rollback des XA-Zweigs aus Der Modus ist ein ernsthafter Rollback, wie wir ihn im herkömmlichen Sinne verstehen, und nicht eine umgekehrte Kompensation.

  • 7. Saga-Modus

Abschließend werfen wir einen Blick auf den Saga-Modus. Dieser Modus wird selten verwendet, Sie können ihn also einfach verstehen. Der

Saga-Modus ist eine von Seata bereitgestellte Lösung für lange Transaktionen. Lange Transaktionen sollten wir jedoch in der Entwicklung vermeiden, da sie ineffizient sind und leicht zu Deadlocks führen können.

Dieser Saga-Modus ist ein bisschen wie eine Prozess-Engine. Der Entwickler zeichnet zunächst selbst eine Prozess-Engine und bezieht alle an der gesamten Transaktion beteiligten Methoden ein, und was zurückgegeben wird, ist abnormal und normal Wenn es abnormal ist, wird ein weiterer Satz von Prozessen ausgeführt. Der erste Satz ist der Ausführungsprozess für verschiedene normale Situationen. und der zweite Satz ist der Ausführungsprozess nach Auftreten einer Ausnahme, ähnlich wie folgt:

Die grünen sind normale Prozesse und die roten sind die Prozesse, die nach Auftreten einer Ausnahme zurückgesetzt werden. Rollback ist auch eine Art umgekehrte Kompensation.

Das obige ist der detaillierte Inhalt vonSo lösen Sie das Problem der verteilten Java Spring Boot-Transaktionen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen