Dieser Artikel wird eingehende Forschungen zum Transaktionsmanagement von Spring durchführen. Fördert hauptsächlich, wie @Transactional unten funktioniert. Der folgende Artikel wird vorgestellt:
Verwendung von Attributen wie Ausbreitung (Transaktionsausbreitung) und Isolation (Isolation)
Was sind die Fallstricke des Transaktionsgebrauchs und wie man es vermeidet?
JPA- und Transaktionsmanagement
Es ist wichtig, dass JPA selbst keine deklarative Transaktionsmanagement bietet. Wenn Sie JPA außerhalb eines Abhängigkeitsinjektionsbehälters verwenden, muss die Transaktion vom Entwickler programmatisch implementiert werden.
UserTransaction utx = entityManager.getTransaction (); try {utx.begin (); BusinessLogic (); utx.commit ();} catch (Ausnahme ex) {utx.rollback (); ThrowEx;};};Diese Art des Transaktionsmanagements ermöglicht es dem Transaktionsumfang, im Code klar ausgedrückt zu werden, hat jedoch die folgenden Nachteile:
Wiederholter Code und Fehler sind anfällig für
Fehler können einen größeren Einfluss haben
Fehler sind schwer zu debugieren und zu reproduzieren
Reduziert die Lesbarkeit der Codebasis
Was ist, wenn die Methode andere Transaktionsmethoden aufruft?
Verwenden Sie Spring @Transactional
Mit Spring @Transactional wird der obige Code vereinfacht zu:
@Transactional PublicVoid BusinessLogic () {... Verwenden Sie den Entitätsmanager in einer Transaktion ...}Der Code ist prägnanter und lesbarer und ist auch die empfohlene Möglichkeit, derzeit im Frühjahr zu handeln.
Viele wichtige Aspekte wie die Transaktionsausbreitung können automatisch mit @Transactional behandelt werden. Wenn BusinessLogic () eine andere Transaktionsmethode aufruft, bestimmt die Methode, wie Sie die laufende Transaktion basierend auf den Optionen verbinden.
Ein potenzieller Nachteil dieses leistungsstarken Mechanismus ist, dass er die zugrunde liegende Operation verbirgt und schwer zu debuggen ist, wenn er nicht richtig funktioniert.
@Transactional Bedeutung
Einer der wichtigsten Punkte zu @Transactional ist die Berücksichtigung von zwei getrennten Konzepten, die beide ihren eigenen Umfang und ihren Lebenszyklus haben:
Persistenzkontext (Persistenzkontext)
Datenbanktransaktion
@Transactional selbst definiert den Umfang einer einzelnen Transaktion. Diese Transaktion liegt im Rahmen des Persistenzkontexts.
Der Persistenzkontext in JPA ist entityManager, und die interne Implementierung verwendet die Hibernate -Sitzung (mithilfe von Hibernate als Persistenzanbieter).
Der Persistenzkontext ist nur ein synchrones Objekt, das den Status von Java -Objekten einer endlichen Sammlung aufzeichnet und sicherstellt, dass Änderungen in diesen Objekten letztendlich in der Datenbank bestehen bleiben.
Dies ist ein ganz anderes Konzept als eine einzelne Transaktion. Ein Entitätsmanager kann über mehrere Transaktionen hinweg verwendet werden und wird tatsächlich auf diese Weise verwendet.
Wann umfasst EntityManager mehrere Transaktionen?
Die häufigste Situation ist, wenn eine Anwendung eine offene Sitzung im Ansichtsmodus verwendet, um faule Initialisierungsausnahmen zu verarbeiten. Frühere Artikel haben die Vor- und Nachteile dieses Ansatzes eingeführt.
In diesem Fall befinden sich mehrere Abfragen, die von der Ansichtsschicht ausgeführt wurden, in separaten Transaktionen und nicht in einer einzelnen Transaktionsgeschäftslogik. Diese Abfragen werden jedoch von demselben Entitätsmanager verwaltet.
Ein weiteres Szenario ist, dass der Entwickler den Persistenzkontext als PersistenCeContextType.uthed markiert, was bedeutet, dass er auf mehrere Anfragen reagieren kann.
Wie kann man die Beziehung zwischen EntityManager und Transaktion definieren?
Dies wird von Anwendungsentwicklern ausgewählt, aber die häufigste Möglichkeit für den JPA -Entitätsmanager ist der Modus "Entity Manager pro Anwendungstransaktion". Häufige Methoden der Injektion von Entity Manager sind:
@Persistencontext PrivateEntityManager Em;
Der Standardwert ist der Modus "Entity Manager pro Transaktion". In diesem Modus wird die Methode in einer einzigen Transaktion ausgeführt, wenn der Entitätsmanager in der @Transactional -Methode verwendet wird.
Wie funktioniert @PersistenceContext?
Die folgende Frage ist, wie @PersistenContext der Entitätsmanager nur dann injizieren kann, wenn der Container beginnt, vorausgesetzt, der Lebenszyklus des Entity -Managers ist kurz und erfordert mehrere Entitätsmanager pro Anfrage.
Die Antwort ist, dass es nicht: EntityManager ist eine Schnittstelle, und was in die Spring Bean injiziert wird, ist nicht der Entitätsmanager selbst, sondern der Kontext -AWARE -Proxy (Context AWare Proxy) des spezifischen Entitätsmanagers in der Laufzeit.
Die spezifische Klasse, die üblicherweise für Proxy verwendet wird, ist SharedEntityManagerInvocationHandler, der mit Hilfe eines Debuggers bestätigt werden kann.
Wie funktioniert @Transactional?
Der anhaltende Kontextproxy, der die EntityManager -Schnittstelle implementiert, ist nicht der einzige Teil des Deklarativen -Transaktionsmanagements, sondern enthält tatsächlich drei Komponenten:
EntityManager -Proxy selbst
Der Abschnitt der Transaktion
Transaktionsleiter
Schauen Sie sich diese drei Teile und ihre Interaktionen an.
Der Abschnitt der Transaktion
Der Transaktionsabschnitt ist ein Abschnitt "um", der vor und nach der kommentierten Geschäftsmethode aufgerufen werden kann. Die spezifische Klasse, die den Abschnitt implementiert, ist der Transaktionsinterceptor.
Der Abschnitt einer Transaktion enthält zwei Hauptaufgaben:
In 'Bevor' enthält der Abschnitt einen Anrufpunkt, um zu entscheiden, ob die aufgerufene Geschäftsmethode im Rahmen der laufenden Transaktion ausgeführt oder eine neue unabhängige Transaktion starten soll.
In 'After' muss der Abschnitt feststellen, dass die Transaktion festgelegt, zurückgerollt oder fortgesetzt wird.
In 'Bevor' enthält der Transaktionsabschnitt selbst keine Entscheidungslogik, und die Entscheidung, eine neue Transaktion zu starten, wird zum Abschluss an den Transaktionsmanager delegiert.
Transaktionsleiter
Der Transaktionsleiter muss die folgenden zwei Probleme lösen:
Sollte der neue Unternehmen Manager erstellt werden?
Sollte eine neue Transaktion gestartet werden?
Diese erfordern, dass Transaktionsabschnitte festgelegt werden, wenn die "Vorher" -Logik aufgerufen wird. Die Entscheidungen des Transaktionsmanagers basieren auf den folgenden zwei Punkten:
Ist die Transaktion weiter
Die Ausbreitungseigenschaft der Transaktionsmethode (beispielsweise erfordert, dass_New immer eine neue Transaktion startet)
Wenn der Transaktionsmanager feststellt, dass Sie eine neue Transaktion erstellen möchten, wird dies:
1. Erstellen Sie einen neuen Entitätsmanager
2. Der Intity Manager ist an den aktuellen Thread gebunden
3. Nehmen Sie eine Verbindung aus dem Datenbankverbindungspool ab
4. Binden Sie die Verbindung an den aktuellen Thread
Verwenden Sie die ThreadLocal -Variable, um sowohl den Entity -Manager als auch die Datenbankverbindung an den aktuellen Thread zu binden.
Transaktionen werden ausgeführt, wenn sie im Thread gespeichert werden, und wenn sie nicht mehr verwendet werden, entscheidet der Transaktionsmanager, ob sie gelöscht werden sollen.
Jeder Teil des Programms kann aus dem Thread abgerufen werden, wenn der aktuelle Entitätsmanager und die Datenbankverbindung erforderlich sind.
EntityManager Proxy
EntityManager -Proxy (bereits zuvor eingeführt) ist der letzte Teil des Puzzles. Wenn die Geschäftsmethode EntityManager.Persist () aufruft, wird dies vom Entity Manager nicht direkt aufgerufen.
Stattdessen ruft die Geschäftsmethode den Agenten auf, der den aktuellen Entitätsmanager aus dem Thread erhält. Wie bereits erwähnt, bindet der Transaktionsmanager den Entitätsmanager an den Thread.
Nachdem wir die verschiedenen Teile des @Transactional -Mechanismus verstanden haben, schauen wir uns die häufig verwendeten Federkonfigurationen an, die sie implementieren.
Drei Teile integrieren
Wie kombiniert ich drei Teile, damit Transaktionsanmerkungen korrekt funktionieren können? Definieren Sie zuerst die Entitätsmanager -Fabrik.
Auf diese Weise können Sie Entity Manager -Proxy mit Annotation von Persistenzkontext injizieren.
@Configuration publicClass EntityManagerFactoryConfiguration {@Autowired PrivatedataSource DataSource; @Bean (name = "EntityManagerFactory") publicLocalContainerEntityManagerFactoryBean EMF () {lokalContainerEntityManagerFactoryBean EMF = ... EMF.SetDataSource (DataSource); emf.setpackagestoscan (NewString [] {"Your.package"}); emf.setjpavendoradapter (newiberNatejpavendoradapter ()); returnemf;}}}Der nächste Schritt besteht darin, den Transaktionsmanager zu konfigurieren und die Transaktionsfacetten in der annotierten Klasse @Transactional anzuwenden.
@Configuration @enabletransactionManagement publicClass transactionManagersconfig {@autowired entityManagerFactory EMF; @autowired privatataSource DataSource; @Bean (name = "transactionManager") publicPlatformTransactionManager TransactionManager () {jpatransactionManager tm = newJpatransactionManager (); tm.setEntityManagerFactory (EMF);Annotation @EnableTransactionManagement benachrichtigt den Frühling, dass die von @Transactional kommentierte Klasse von der Ausschnitten der Transaktion umgeben ist. Auf diese Weise kann @Transactional verwendet werden.
Zusammenfassen
Der deklarative Transaktionsmanagement -Mechanismus von Spring ist sehr leistungsfähig, kann jedoch missbraucht oder leicht zu konfigurieren.
Wenn Probleme wie dieser Mechanismus nicht ordnungsgemäß funktionieren oder die erwarteten Betriebsergebnisse nicht erzielen, ist es hilfreich, die internen Arbeiten zu verstehen.
Das Wichtigste, an das Sie sich erinnern sollten, ist, zwei Konzepte zu berücksichtigen: Transaktionen und Persistenzkontexte, die jeweils ihren eigenen offensichtlichen Lebenszyklus sind, der unleserlich ist.
Das obige ist der gesamte Inhalt dieses Artikels über das Arbeitsprinzip von Spring @Transactional. Ich hoffe, es wird für alle hilfreich sein. Interessierte Freunde können weiterhin auf andere verwandte Themen auf dieser Website verweisen. Wenn es Mängel gibt, hinterlassen Sie bitte eine Nachricht, um darauf hinzuweisen. Vielen Dank an Freunde für Ihre Unterstützung für diese Seite!