In den frühen Tagen des Rechnens waren keine verteilten Transaktionen erforderlich. Mit zunehmender Anzahl von Anwendungen wird die Synchronisierung der Daten zu einem wichtigen Thema. Unternehmen haben viel bezahlt, um synchronisierte Systeme in Bezug auf den Datenfluss aufrechtzuerhalten. Als Ergebnis entstand das als XA (eXtended Architecture) bezeichnete 2-Phasen-Commit-Protokoll. Dieses Protokoll bietet ACID-ähnliche Eigenschaften für die globale Transaktionsverarbeitung. In diesem Artikel werde ich versuchen, Details zu XA-Transaktionen und zur Verwendung von XA-Transaktionen in Spring Framework zu erläutern.
2 phase commit protocol ist ein atomares Commit-Protokoll für verteilte Systeme. Dieses Protokoll besteht, wie der Name schon sagt, aus zwei Phasen. Die erste ist die Commit-Request-Phase, in der der Transaction Manager alle Transaktionsressourcen koordiniert, die festgeschrieben oder abgebrochen werden sollen. In der Festschreibungsphase entscheidet der Transaktionsmanager, den Vorgang durch Festschreiben oder Abbrechen gemäß den Stimmen der einzelnen Transaktionsressourcen abzuschließen. Wir werden als nächstes zu den Implementierungsdetails des 2PC-Protokolls übergehen.
*Ressourcen zur Interoperabilität von Java + .NET über 2PC finden Sie hier.
XA-Transaktionen benötigen eine globale Transaktions-ID und eine lokale Transaktions-ID(xid) für jede XA-Ressource. Jede XA-Ressource wird per start (xid) -Methode in XA Manager eingetragen. Diese Methode teilt mit, dass eine XA-Ressource an der Transaktion beteiligt ist (bereit für Operationen sein). Danach wird die erste Phase des 2PC-Protokolls durch Aufrufen der prepare (xid) -Methode realisiert. Diese Methode fordert OK oder ABORT vote von der XA-Ressource an. Nach dem Empfang der Abstimmung von jeder XA-Ressource entscheidet der XA-Manager, eine Commit-Operation (xid) auszuführen, wenn alle XA-Ressourcen OK senden, oder beschließt, ein Rollback (xid) auszuführen, wenn eine XA-Ressource ABORT sendet. Schließlich wird die End-Methode (xid) für jede XA-Ressource aufgerufen, die angibt, dass die Transaktion abgeschlossen ist. Schauen Sie sich die Abbildung an, um sie besser zu verstehen. Während wir einen Hintergrund in der XA-Transaktionsimplementierung aufbauen, werden wir als nächstes tiefer gehen und Arten von Fehlern und mögliche Lösungen sehen.
Ausfälle können jederzeit aufgrund von Netzwerkverlust, Maschinenstillstand und Administratorfehlern auftreten. In XA transaction werden wir diese Fehler nach den Phasen kategorisieren, in denen sie auftreten. Die erste Fehlerphase ist, bevor das Protokoll gestartet wird. Dies ist ein einfacher Fehler, dass das System nicht Rollback oder irgendeine Art von Operation braucht. Wir machen die Operation einfach nicht für diesen bestimmten Moment. Die zweite Art von Fehler kann in der Vorbereitungsphase (Commit-Request) auftreten, die leicht durch Rollbacks mit Timeout-Richtlinien gehandhabt werden kann. Last but not least sind Commit-Phasenausfälle, die aufgrund unvollständiger Rollbacks und Probleme in der Kette auftreten können. In all diesen oben genannten Situationen versucht Transaction Manager, das Problem zu beheben. Wir werden als nächstes sehen, wie Transaction Manager versucht, Fehler zu überwinden.
Für die Wiederherstellung ruft Transaction Manager die Wiederherstellungsmethode jeder XA-Ressource auf. XA Resources verfolgt die Protokolle und versucht, den neuesten Zustand wiederherzustellen. Transaction Manager ruft notwendige Rollback-Operationen auf und die Mission ist erfüllt. Dieser Prozess scheint glücklich zu sein, aber es gibt viele Ausnahmesituationen, in denen Protokolle problematisch sind, z. B. beschädigt zu werden. In solchen Situationen folgt Transaction Manager einigen Heuristiken, um das Problem zu lösen. Darüber hinaus hängt der Wiederherstellungsprozess von den Write-Ahead-Protokollen ab, in die Sie vor der Anwendung Vorgangsprotokolle schreiben. Bei Leistungsproblemen werden diese Protokolle in ihrem eigenen Format geschrieben (ohne Serialisierung), und das System sollte sie nach Möglichkeit besser stapeln. Als nächstes gehen wir zum lustigen Teil, der XA-Transaktionsunterstützung durch Spring Framework ist.
Spring Framework bietet eine umfangreiche Umgebung zur Entwicklung von Web- und eigenständigen Anwendungen. Wie andere Dienstprogramme werden auch XA-Transaktionen von Spring unterstützt. Diese Unterstützung ist jedoch keine native Implementierung und erfordert Ruhezustand, Webcontainer oder ein Framework, das XA-Transaktionsmanagement bereitstellt. Spring verfügt über JtaTransactionManager, der Dienstprogramme zur Transaktionsverwaltung bereitstellt und die Details verbirgt. Auf diese Weise können wir Transaktionsmanagement für mehrere Datenquellen haben, die gleichzeitig aktualisiert werden. Wenn es darum geht, XA Transaction Management, Hibernate und Web-Container-Unterstützung für XA-Transaktionen zu verwenden, sind gut dokumentiert, müssen nicht erwähnt werden. Die Arbeit mit einem Framework, das XA-Transaktionen bereitstellt, kann jedoch verwirrend sein. Daher werde ich diesen Beitrag mit der Einführung von Bitronix Transaction Manager fortsetzen.
Bitronix ist einfach zu konfigurieren und bietet gleichzeitig eine gute Unterstützung für das Transaktionsmanagement. Es wird nicht häufig in eigenständigen Anwendungen verwendet, aber ich werde versuchen, die Konfiguration für eigenständige Anwendungen wie folgt vorzunehmen.
<bean factory-method="getConfiguration" class="bitronix.tm.TransactionManagerServices"> <!--Disabling Jmx avoids registering JMX Beans to any container--> <property name="disableJmx" value="true" /></bean><bean factory-method="getTransactionManager" class="bitronix.tm.TransactionManagerServices" depends-on="bitronixTMConfig" destroy-method="shutdown"/><bean class="org.springframework.transaction.jta.JtaTransactionManager"> <property name="transactionManager" ref="bitronixTM" /> <property name="userTransaction" ref="bitronixTM" /> <property name="allowCustomIsolationLevels" value="true" /></bean>
Wir können jetzt mehrere Datenquellen haben, die wie folgt konfiguriert werden können. Jede Datenquelle sollte eine uniqueName-Eigenschaft haben, die eindeutig ist. Die folgende Konfiguration gilt für Oracle, andere Datenbanken können unterschiedliche Konfigurationen haben. Für jedes andere Detail können Sie die Bitronix-Website besuchen.
<bean class="bitronix.tm.resource.jdbc.PoolingDataSource" init-method="init" destroy-method="close"> <property name="uniqueName" value="xaDataSource" /> <property name="minPoolSize" value="1" /> <property name="maxPoolSize" value="4" /> <property name="testQuery" value="SELECT 1 FROM dual" /> <property name="driverProperties"> <props> <prop key="URL">jdbc:oracle:thin:@10.6.86.24:1521:test</prop> <prop key="user">test</prop> <prop key="password">test</prop> </props> </property> <property name="className" value="oracle.jdbc.xa.client.OracleXADataSource" /> <property name="allowLocalTransactions" value="true" /></bean>
Zusammenfassend haben wir versucht zu erklären, was XA-Transaktionen, zugrunde liegende Protokolle und die Integration von Bitronix Transaction Management mit Spring in einer eigenständigen Anwendung sind. Zur Erweiterung bietet XA Transactions das gleichzeitige Ändern verschiedener Datenquellen. Darüber hinaus werden XA-Transaktionen von Webcontainern oder Hibernate-ähnlichen Frameworks unterstützt. Dennoch müssen wir möglicherweise das Transaktionsmanagement in eine eigenständige Anwendung integrieren, in der wir den Transaktionsmanager konfigurieren müssen. Infolgedessen bietet XA Transaction konsistente Vorgänge für mehrere Datenquellen, die von Unternehmen verwendet werden.
*Anmerkungen des Kurators und zusätzliche Ressourcen