Het is helemaal niet ingewikkeld.
-
Ten eerste moet u begrijpen dat de Spring-transactiemanager slechts een abstractie van transactiebeheer is. In uw geval vinden de daadwerkelijke transacties plaats op het JDBC-verbindingsniveau.
-
Allemaal
@Transactional
aanroepen van servicemethoden worden onderschept door deTransactionInterceptor
Aspect. -
De
TransactionIntreceptor
delegeert transactiebeheer aan de huidige geconfigureerdeAbstractPlatformTransactionManager
implementatie (JpaTransactionManager
in jouw geval). -
JpaTransactionManager
bindt de huidige lopende Spring-transactie aan een EntityManager, zodat alle DAO's die deelnemen aan de huidige transactie dezelfde Persistence Context delen. -
JpaTransactionManager
gebruikt gewoon deEntityManager
Transactie-API voor het controleren van transacties:EntityTransaction tx = txObject.getEntityManagerHolder().getEntityManager().getTransaction(); tx.commit();
De JPA Transaction API delegeert de aanroep eenvoudig naar de onderliggende JDBC Connection commit/rollback-methoden.
-
Wanneer de transactie is voltooid (commit/rollback), wordt de
org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction
oproepen:transactionCoordinator().getTransactionContext().managedClose();
die een Hibernate Session (Entity Manager) sluiting activeert.
-
De onderliggende JDBC-verbinding wordt daarom ook geactiveerd om te worden gesloten:
jdbcCoordinator.close();
-
Hibernate heeft een logische JDBC-verbindingshandle:
@Override public Connection close() { LOG.tracev( "Closing JDBC container [{0}]", this ); if ( currentBatch != null ) { LOG.closingUnreleasedBatch(); currentBatch.release(); } cleanup(); return logicalConnection.close(); }
-
De logische verbinding delegeert de close call naar de momenteel geconfigureerde verbindingsprovider (
DataSourceConnectionProvider
in jouw geval), die simpelweg de close-methode op de JDBC-verbinding aanroept:@Override public void closeConnection(Connection connection) throws SQLException { connection.close(); }
-
Net als elke andere DataSource-pooling van verbindingen, retourneert de JDBC-verbinding close eenvoudig de verbinding met de pool en sluit de fysieke databaseverbinding niet. Dat komt omdat de verbindingspooling DataSource een JDBC-verbindingsproxy retourneert die alle oproepen onderschept en het sluiten delegeert aan de logica voor het afhandelen van de verbindingspool.
Houd er rekening mee dat u voor RESOURCE_LOCAL-transacties ook de hibernate.connection.provider_disables_autocommit
eigenschap als de autocommit
check is uitgeschakeld door de verbindingspool. Op deze manier worden de databaseverbindingen lui verkregen voordat een SQL-query wordt uitgevoerd of de persistentiecontext wordt gewist.