Wann werden Verbindungen mit Spring JPA (Hibernate) Entity Manager zum Verbindungspool zurückgegeben?

8

In meinem Java-Prozess verbinde ich mich mit MySql unter Verwendung der folgenden Frühlingskonfiguration:

%Vor%

Der Entity-Manager wird vom Container in die Datenzugriffsebene injiziert:

%Vor%

Und meine öffentlichen Geschäftslogik-Methoden sind mit der Annotation @Transactional versehen.

Soweit ich weiß, ist der Container dafür verantwortlich, dass der Entity-Manager Verbindungen zum Pool zurückgibt (in meinem Fall HikariCP ) Sobald eine Transaktion abgeschlossen ist, habe ich keine offizielle Dokumentation gefunden, die beschreibt, wie die Verbindungen verwaltet werden. Kann mir das jemand erklären oder eine gute Referenz geben, die erklären kann, wann genau Verbindungen bei einer solchen Konfiguration in den Pool zurückgeführt werden?

UPDATE:

Die besten Informationen, die mir bisher einfielen ( von hier ) >):

Der Persistenzkontextproxy, der EntityManager implementiert, ist nicht die einzige Komponente, die für das Funktionieren der deklarativen Transaktionsverwaltung benötigt wird. Tatsächlich werden drei separate Komponenten benötigt:

Der EntityManager-Proxy selbst Der transaktionale Aspekt Der Transaktionsmanager Lassen Sie uns über jeden gehen und sehen, wie sie interagieren.

Der Transaktionsaspekt

Der transaktionale Aspekt ist ein "runder" Aspekt, der vor und nach der annotierten Geschäftsmethode aufgerufen wird. Die konkrete Klasse zur Implementierung des Aspekts ist TransactionInterceptor.

Der transaktionale Aspekt hat zwei Hauptaufgaben:

Im "Vorher" -Moment bietet der Aspekt einen Hook-Punkt, um zu bestimmen, ob die anzuzurufende Geschäftsmethode im Rahmen einer laufenden Datenbanktransaktion ausgeführt werden soll oder ob eine neue separate Transaktion gestartet werden soll.

>

Im "Nachher" -Moment muss der Aspekt entscheiden, ob die Transaktion festgeschrieben, zurückgesetzt oder ausgeführt werden soll.

Im 'Vorher'-Moment enthält der Transaktionsaspekt selbst keine Entscheidungslogik. Die Entscheidung, eine neue Transaktion bei Bedarf zu starten, wird an den Transaktionsmanager delegiert.

Der Transaktionsmanager

Der Transaktionsmanager muss eine Antwort auf zwei Fragen geben:

sollte ein neuer Entity Manager erstellt werden? Soll eine neue Datenbanktransaktion gestartet werden? Dies muss in dem Moment entschieden werden, in dem die Transaktionslogik "vorher" aufgerufen wird. Der Transaktionsmanager entscheidet basierend auf:

die Tatsache, dass eine Transaktion bereits läuft oder nicht das Propagierungsattribut der Transaktionsmethode (zB REQUIRES_NEW startet immer eine neue Transaktion) Wenn der Transaktionsmanager beschließt, eine neue Transaktion zu erstellen, wird Folgendes ausgeführt:

Erstellen Sie einen neuen Entity Manager Binden Sie den Entity Manager an den aktuellen Thread Nimm eine Verbindung vom DB-Verbindungspool Binden Sie die Verbindung an den aktuellen Thread Der Entity Manager und die Verbindung sind mit ThreadLocal-Variablen an den aktuellen Thread gebunden.

Sie werden im Thread gespeichert, während die Transaktion ausgeführt wird, und es obliegt dem Transaction Manager, sie zu bereinigen, wenn sie nicht mehr benötigt werden.

Alle Teile des Programms, die den aktuellen Entity Manager oder die aktuelle Verbindung benötigen, können sie aus dem Thread abrufen. Eine Programmkomponente, die genau das tut, ist der EntityManager-Proxy.

    
forhas 15.12.2014, 14:19
quelle

1 Antwort

16

Es ist überhaupt nicht kompliziert.

  1. Zuerst müssen Sie verstehen, dass der Spring Transaktionsmanager nur ein Transaktionsmanagement Abstraktion . In Ihrem Fall finden die tatsächlichen Transaktionen auf JDBC-Verbindungsebene statt.

  2. Alle @Transactional-Service-Methodenaufrufe werden vom TransactionInterceptor-Aspekt abgefangen.

  3. Der TransactionIntreceptor delegiert die Transaktionsverwaltung an die aktuelle Konfiguration AbstractPlatformTransactionManager Implementierung (in Ihrem Fall JpaTransactionManager) .

  4. JpaTransactionManager bindet die aktuell ausgeführte Spring-Transaktion an einen EntityManager, so dass alle DAOs, die an der aktuellen Transaktion teilnehmen, den gleichen Persistenzkontext haben.

  5. JpaTransactionManager verwendet einfach die EntityManager-Transaktions-API zum Steuern von Transaktionen:

    %Vor%

    Die JPA-Transaktions-API delegiert den Aufruf einfach an die zugrunde liegenden JDBC-Verbindungs-Commit / Rollback-Methoden.

  6. Wenn die Transaktion abgeschlossen ist (commit / rollback), ruft org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction:

    auf %Vor%

    , wodurch eine Hibernate-Sitzung (Entity Manager) geschlossen wird.

  7. Die zugrunde liegende JDBC-Verbindung wird daher ebenfalls als geschlossen ausgelöst:

    %Vor%
  8. Hibernate verfügt über eine logische JDBC-Verbindungskennung:

    %Vor%
  9. Der Handle für die logische Verbindung delegiert den Schließen-Aufruf an den aktuell konfigurierten Verbindungsanbieter (in Ihrem Fall DataSourceConnectionProvider), der einfach die Methode close für die JDBC-Verbindung aufruft:

    %Vor%
  10. Wie bei jeder anderen Verbindungspooling-DataSource gibt die JDBC-Verbindung die Verbindung einfach zurück in den Pool und schließt die physische Datenbankverbindung nicht. Das liegt daran, dass die DataSource-Verbindungspooling-Verbindung einen JDBC-Verbindungsproxy zurückgibt, der alle Aufrufe abfängt und das Schließen an die Logik zur Verarbeitung des Verbindungspools delegiert.

Vlad Mihalcea 23.12.2014, 06:35
quelle

Tags und Links