Es ist überhaupt nicht kompliziert.
-
Zunächst müssen Sie verstehen, dass der Spring-Transaktionsmanager nur eine Transaktionsverwaltungsabstraktion ist. In Ihrem Fall finden die eigentlichen Transaktionen auf der JDBC-Verbindungsebene statt.
-
Alle
@Transactional
Dienstmethodenaufrufe werden vomTransactionInterceptor
abgefangen Aspekt. -
Der
TransactionIntreceptor
delegiert die Transaktionsverwaltung an den aktuell konfiguriertenAbstractPlatformTransactionManager
Implementierung (JpaTransactionManager
in Ihrem Fall). -
JpaTransactionManager
bindet die aktuell laufende Spring-Transaktion an einen EntityManager, sodass alle DAOs, die an der aktuellen Transaktion teilnehmen, denselben Persistenzkontext teilen. -
JpaTransactionManager
verwendet einfach denEntityManager
Transaktions-API zur Steuerung von Transaktionen:EntityTransaction tx = txObject.getEntityManagerHolder().getEntityManager().getTransaction(); tx.commit();
Die JPA-Transaktions-API delegiert den Aufruf einfach an die zugrunde liegenden Commit-/Rollback-Methoden der JDBC-Verbindung.
-
Wenn die Transaktion abgeschlossen ist (commit/rollback), wird die
org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction
Aufrufe:transactionCoordinator().getTransactionContext().managedClose();
was das Schließen einer Hibernate Session (Entity Manager) auslöst.
-
Das Schließen der zugrunde liegenden JDBC-Verbindung wird daher ebenfalls ausgelöst:
jdbcCoordinator.close();
-
Hibernate hat ein logisches JDBC-Verbindungshandle:
@Override public Connection close() { LOG.tracev( "Closing JDBC container [{0}]", this ); if ( currentBatch != null ) { LOG.closingUnreleasedBatch(); currentBatch.release(); } cleanup(); return logicalConnection.close(); }
-
Die logische Verbindung delegiert den Close-Aufruf an den aktuell konfigurierten Verbindungsanbieter (
DataSourceConnectionProvider
in Ihrem Fall), die einfach die close-Methode für die JDBC-Verbindung aufruft:@Override public void closeConnection(Connection connection) throws SQLException { connection.close(); }
-
Wie bei jeder anderen Datenquelle für das Verbindungspooling gibt das Schließen der JDBC-Verbindung einfach die Verbindung zum Pool zurück und schließt nicht die physische Datenbankverbindung. Das liegt daran, dass die Datenquelle für das Verbindungspooling einen JDBC-Verbindungsproxy zurückgibt, der alle Aufrufe abfängt und das Schließen an die Verarbeitungslogik für den Verbindungspool delegiert.
Beachten Sie, dass Sie für RESOURCE_LOCAL-Transaktionen auch hibernate.connection.provider_disables_autocommit
-Eigenschaft, wenn die autocommit
check wurde vom Verbindungspool deaktiviert. Auf diese Weise werden die Datenbankverbindungen träge erfasst, bevor eine SQL-Abfrage ausgeführt oder der Persistenzkontext geleert wird.