1 Einführung in das Spring Framework-Transaktionsmanagement
Umfassende Transaktionsunterstützung ist ein überzeugender Grund, das Spring Framework zu verwenden. Das Spring-Framework bietet eine konsistente Abstraktion für das Transaktionsmanagement mit den folgenden Vorteilen:
Ein konsistentes Programmiermodell über verschiedene Transaktions-APIs hinweg, wie z. B. Java Transaction API (JTA), JDBC, Hibernate, Java Persistence API (JPA). und Java Data Objects (JDO).
Unterstützt deklaratives Transaktionsmanagement.
Einfacher als komplexe Transaktions-APIs (z. B. JTA).
Perfekt integriert in die Datenzugriffsabstraktion von Spring.
2 Vorteile des Transaktionsunterstützungsmodells des Spring Frameworks
Traditionell verfügen Java EE-Entwickler über zwei optionale Transaktionsverwaltungsmethoden: globale oder lokale Transaktionen, jede mit ihren eigenen Einschränkungen.
2.1 Globale Transaktionen
Globale Transaktionen ermöglichen Ihnen die Nutzung mehrerer Transaktionsressourcen, normalerweise relationale Datenbanken und Nachrichtenwarteschlangen. Die Anwendung verwaltet globale Transaktionen über JTA, eine umständliche API. Außerdem muss JTA UserTransaction normalerweise von JNDI stammen, was bedeutet, dass Sie JNDI verwenden müssen. Offensichtlich schränkt die Verwendung globaler Transaktionen die Wiederverwendung von Anwendungscode ein, da JTA normalerweise nur in einer Anwendungsserverumgebung verfügbar ist.
In der Vergangenheit war die bevorzugte Art der Nutzung globaler Transaktionen EJB CMT (Container Managed Transactions): CMT ist deklaratives Transaktionsmanagement. EJB CMT löscht die JNDI-Suche nach zugehörigen Transaktionen, aber EJB selbst muss JNDI verwenden. Es macht das Schreiben von Java-Code zur Steuerung von Transaktionen größtenteils (aber nicht vollständig) überflüssig. Der wesentliche Nachteil besteht darin, dass CMT JTA- und Anwendungsserverumgebungen bündelt. Gleichzeitig funktioniert es nur, wenn EJBs zur Implementierung der Geschäftslogik verwendet werden, oder zumindest innerhalb einer transaktionalen EJB-Fassade.
2.2 Lokale Transaktionen
Lokale Transaktionen sind bestimmte Ressourcen, Transaktionen sind beispielsweise mit JDBC-Verbindungen verknüpft. Lokale Transaktionen sind einfach zu verwenden, haben jedoch einen erheblichen Nachteil: Sie können nicht mehrere Transaktionsressourcen umfassen. Beispielsweise können Transaktionen, die über eine JDBC-Verbindung verwaltet werden, nicht innerhalb einer globalen JTA-Transaktion ausgeführt werden. Da der Anwendungsserver nicht für die Transaktionsverwaltung verantwortlich ist, kann er keine ressourcenübergreifende Korrektheit garantieren. Ein weiterer Nachteil ist das aufdringliche Programmiermodell lokaler Transaktionen.
2.3 Das konsistente Programmiermodell des Spring-Frameworks
Spring behebt die Mängel globaler und lokaler Transaktionen. Es ermöglicht Entwicklern, in jeder Umgebung ein konsistentes Programmiermodell zu verwenden. Entwickler müssen lediglich ihren eigenen Code schreiben, wodurch die unterschiedliche Transaktionsverwaltung in verschiedenen Umgebungen abstrahiert wird. Das Spring-Framework bietet deklaratives und programmatisches Transaktionsmanagement. Die meisten Benutzer bevorzugen die deklarative Transaktionsverwaltung, die ebenfalls empfohlen wird.
Mithilfe der programmgesteuerten Transaktionsverwaltung nutzen Entwickler die Transaktionsabstraktion des Spring-Frameworks, die für jede zugrunde liegende Transaktion ausgeführt werden kann. Bei Verwendung des bevorzugten deklarativen Modells schreiben Entwickler in der Regel wenig oder keinen Transaktionsverwaltungscode und verlassen sich daher nicht auf die Spring Framework-Transaktions-API oder andere Transaktions-APIs.
3 Verständnis der Spring Framework-Transaktionsabstraktion
Der Schlüssel zur Spring-Transaktionsabstraktion ist das Konzept der Transaktionsstrategie. Die Transaktionsstrategie wird über die Schnittstelle org.springframework.transaction.PlatformTransactionManager definiert:
public interface PlatformTransactionManager {
TransactionStatus getTransaction(
TransactionDefinition definition) löst TransactionException aus;
void commit(TransactionStatus status) löst TransactionException aus;
void rollback(TransactionStatus status) löst TransactionException aus;
}
Dies ist in erster Linie eine Service Provider Interface (SPI), obwohl sie Programmiermodelle in Ihrem Code verwenden kann. Da es sich bei PlatformTransactionManager um eine Schnittstelle handelt, lässt sie sich leicht verspotten und stubben. Es ist keine Suchstrategie wie JNDI erforderlich. PlatformTransactionManager wird wie andere im Spring IoC-Container definierte Objekte implementiert. Aufgrund dieses Vorteils lohnt es sich, Spring Framework-Transaktionen zu abstrahieren, selbst wenn JTA verwendet wird. Transaktionscode ist einfacher zu testen als die direkte Verwendung von JTA.
Die von der PlatformTransactionManager-Schnittstellenmethode ausgelöste TransactionException ist eine unentdeckte Ausnahme (d. h. sie erbt java.lang.RuntimeException). Ein Transaktionsfehler ist fatal. In den seltenen Fällen, in denen der Anwendungscode nach einem Transaktionsfehler tatsächlich wiederhergestellt werden kann, kann der Anwendungsentwickler entscheiden, TransactionException abzufangen und zu behandeln. Der Vorteil besteht darin, dass Entwickler dies nicht erzwingen müssen.
Die Methode getTransaction(..) basiert auf dem Parameter TransactionDefinition, um das TransactionStatus-Objekt zurückzugeben. Der zurückgegebene TransactionStatus kann eine neue Transaktion oder eine vorhandene Transaktion darstellen, wenn die entsprechende Transaktion im aktuellen Aufrufstapel vorhanden ist. Tatsächlich ist dies der letztere Fall. Genau wie der Java EE-Transaktionskontext ist TransactionStatus mit ausführbaren Transaktionen verknüpft.
TransactionDefinition-Schnittstellenbeschreibung:
Isolation (Transaktionsisolationsstufe): Transaktionsisolationsstufe. Kann diese Transaktion beispielsweise andere nicht festgeschriebene Transaktionen lesen?
Weitergabe (Transaktionsweitergabe): Normalerweise wird der gesamte im Transaktionsbereich ausgeführte Code innerhalb der Transaktion ausgeführt. Sie haben jedoch die Möglichkeit, das Verhalten der Transaktionsmethodenausführung anzugeben, wenn bereits ein Transaktionskontext vorhanden ist. Beispielsweise kann der Code in einer bestehenden Transaktion weiter ausgeführt werden (die übliche Situation); oder die bestehende Transaktion kann angehalten und eine neue Transaktion erstellt werden.
Transaktionszeitlimit: Wie lange dauert die Ausführung der Transaktion, bevor sie abläuft und automatisch durch die zugrunde liegende Transaktion zurückgesetzt wird?
Schreibgeschützter Zustand: Schreibgeschützte Transaktionen können verwendet werden, wenn Ihr Code Daten liest, aber nicht ändert. In einigen Fällen sind schreibgeschützte Transaktionen für die Optimierung von Vorteil, beispielsweise wenn Sie Hibernate verwenden.
Diese Einstellungen spiegeln Standardtransaktionskonzepte wider. Diese zugrunde liegenden Konzepte sind ein wesentlicher Bestandteil der Verwendung des Spring Frameworks oder einer anderen Transaktionsverwaltungslösung.
Die TransactionStatus-Schnittstelle bietet eine einfache Möglichkeit für Transaktionscode, ausführbare Transaktionen zu steuern und den Transaktionsstatus abzufragen:
öffentliche Schnittstelle TransactionStatus erweitert SavepointManager {
boolean isNewTransaction ();
boolean hasSavepoint();
void setRollbackOnly();
boolean isRollbackOnly();
void flush();
boolean isCompleted();
}
Unabhängig davon, ob Sie sich in Spring für deklaratives oder programmatisches Transaktionsmanagement entscheiden, ist die Definition der richtigen PlatformTransactionManager-Implementierung von entscheidender Bedeutung. Normalerweise definieren Sie diese Implementierung über die Abhängigkeitsinjektion.
PlatformTransactionManager muss normalerweise die Arbeitsumgebung kennen: JDBC, JTA, Hibernate usw. Unten finden Sie ein Beispiel für die Definition eines lokalen PlatformTransactionManager.
JDBC-Datenquelle definieren:
destroy-method="close" > ;
PlatformTransactionManager-Definition verweist auf die DataSource-Definition:
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> Wenn Sie JTA in einem Java EE-Container verwenden, können Sie die DataSource des Containers mithilfe von JNDI und Springs JtaTransactionManager abrufen: xmlns:xsi =" http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee" xsi :schemaLocation = " 🎜 > http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd"> JtaTransactionManager muss nichts über die DataSource oder eine bestimmte Ressource wissen, da es die globale Transaktionsverwaltung des Containers nutzt. Sie können auch die lokalen Transaktionen von Hibernate verwenden. In diesem Fall müssen Sie die LocalSessionFactoryBean von Hibernate definieren, die Ihr Anwendungscode verwendet, um eine Hibernate-Sitzungsinstanz abzurufen. In diesem Fall ist die txManager-Bean HibernateTransactionManager. So wie DataSourceTransactionManager auf DataSource verweisen muss, muss HibernateTransactionManager auf SessionFactory verweisen: hibernate.dialect=${hibernate.dialect}
如果你使用Hibernate和Java an id="txManager " class="org.springframework.transaction.jta.JtaTransactionManager"/> 你仅仅需要改变配置来改变如何管理事务.
5.2 Beispiele für deklarative Transaktionsimplementierung
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http : //www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http : //www.springframework.org/schema/tx .org/schema/aop http://www.spingframework.org/schema/aop/spring- aop.xsd "& & gt; & lt; ; Schreibgeschützte Methoden beginnen mit „get“ --> Andere Methoden verwenden die Standardeinstellungen --> tx:advice> (..))"/> ,, ,,,, P, Standardmäßig wird eine Spring-Transaktion nur dann zurückgesetzt, wenn eine Laufzeitausnahme oder ein Fehler ausgelöst wird. Überprüfte Ausnahmen führen nicht dazu, dass Spring-Transaktionen zurückgesetzt werden. Sie können den Ausnahmetyp für das Transaktions-Rollback explizit konfigurieren. Sie können auch den Ausnahmetyp angeben, bei dem die Transaktion nicht verlängert wird: 5.4 Konfigurieren Sie unterschiedliche Transaktionssemantiken für unterschiedliche Beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http ://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http: //www.springframework.org/schema/tx .org/schema/aoP Konfiguration & gt; : pointcut id = "defaultServiceoperation" expression = "Execution (*x.y.service.*service.*(..)) ;> & Lt; AOP: pointcut id="noTxServiceOperation" expression="execution(* x.y.service.ddl.DefaultDdlManager .*(..))"/> > Anmerkungsverwaltung aktivieren: xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http:/ / www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http:/ / www.springframework.org/schema/tx /schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">