Non è affatto complicato.
-
Innanzitutto, è necessario comprendere che il gestore delle transazioni Spring è solo un'astrazione della gestione delle transazioni. Nel tuo caso, le transazioni effettive avvengono a livello di connessione JDBC.
-
Tutto
@Transactional
le chiamate al metodo di servizio vengono intercettate daTransactionInterceptor
Aspetto. -
Il
TransactionIntreceptor
delega la gestione delle transazioni all'attuale configuratoAbstractPlatformTransactionManager
implementazione (JpaTransactionManager
nel tuo caso). -
JpaTransactionManager
collegherà la transazione Spring corrente a un EntityManager, in modo che tutti i DAO che partecipano alla transazione corrente condividano lo stesso contesto di persistenza. -
JpaTransactionManager
usa semplicementeEntityManager
API di transazione per il controllo delle transazioni:EntityTransaction tx = txObject.getEntityManagerHolder().getEntityManager().getTransaction(); tx.commit();
L'API Transaction JPA delega semplicemente la chiamata ai metodi di commit/rollback di connessione JDBC sottostanti.
-
Al termine della transazione (commit/rollback),
org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction
chiamate:transactionCoordinator().getTransactionContext().managedClose();
che attiva una chiusura della sessione di ibernazione (Gestione entità).
-
Viene quindi attivata la chiusura anche della connessione JDBC sottostante:
jdbcCoordinator.close();
-
Hibernate ha un handle di connessione JDBC logico:
@Override public Connection close() { LOG.tracev( "Closing JDBC container [{0}]", this ); if ( currentBatch != null ) { LOG.closingUnreleasedBatch(); currentBatch.release(); } cleanup(); return logicalConnection.close(); }
-
La connessione logica delega la chiamata di chiusura al provider di connessione attualmente configurato (
DataSourceConnectionProvider
nel tuo caso), che chiama semplicemente il metodo close sulla connessione JDBC:@Override public void closeConnection(Connection connection) throws SQLException { connection.close(); }
-
Come qualsiasi altro DataSource di pool di connessioni, la chiusura della connessione JDBC restituisce semplicemente la connessione al pool e non chiude la connessione fisica al database. Questo perché il pool di connessioni DataSource restituisce un proxy di connessione JDBC che intercetta tutte le chiamate e delega la chiusura alla logica di gestione del pool di connessioni.
Tieni presente che per le transazioni RESOURCE_LOCAL, dovresti anche impostare hibernate.connection.provider_disables_autocommit
proprietà se autocommit
il controllo è stato disabilitato dal pool di connessioni. In questo modo, le connessioni al database verranno acquisite pigramente prima di eseguire una query SQL o svuotare il contesto di persistenza.