Não é nada complicado.
-
Primeiro, você precisa entender que o gerenciador de transações Spring é apenas uma abstração de gerenciamento de transações. No seu caso, as transações reais acontecem no nível de conexão JDBC.
-
Todos@Transactional
chamadas de métodos de serviço são interceptadas peloTransactionInterceptor
Aspecto.
-
OTransactionIntreceptor
delega o gerenciamento de transações para oAbstractPlatformTransactionManager
implementação (JpaTransactionManager
no seu caso).
-
JpaTransactionManager
vinculará a transação Spring em execução atual a um EntityManager, para que todos os DAOs participantes da transação atual compartilhem o mesmo contexto de persistência.
-
JpaTransactionManager
simplesmente usa oEntityManager
API de transações para controlar transações:
EntityTransaction tx = txObject.getEntityManagerHolder().getEntityManager().getTransaction(); tx.commit();
A API de transação JPA simplesmente delega a chamada para os métodos de confirmação/reversão de conexão JDBC subjacentes.
-
Quando a transação é concluída (commit/rollback), oorg.hibernate.engine.transaction.internal.jdbc.JdbcTransaction
chamadas:
transactionCoordinator().getTransactionContext().managedClose();
que aciona o fechamento de uma sessão do Hibernate (Entity Manager).
-
A conexão JDBC subjacente é, portanto, acionada para ser fechada também:
jdbcCoordinator.close();
-
O Hibernate tem um identificador de conexão JDBC lógico:
@Override public Connection close() { LOG.tracev( "Closing JDBC container [{0}]", this ); if ( currentBatch != null ) { LOG.closingUnreleasedBatch(); currentBatch.release(); } cleanup(); return logicalConnection.close(); }
-
A conexão lógica delega a chamada próxima ao provedor de conexão configurado no momento (DataSourceConnectionProvider
no seu caso), que simplesmente chama o método close na conexão JDBC:
@Override public void closeConnection(Connection connection) throws SQLException { connection.close(); }
-
Como qualquer outro DataSource de pool de conexões, o fechamento da conexão JDBC simplesmente retorna a conexão com o pool e não fecha a conexão física do banco de dados. Isso porque o DataSource do pool de conexões retorna um proxy de conexão JDBC que intercepta todas as chamadas e delega o fechamento à lógica de manipulação do pool de conexões.
Observe que, para transações RESOURCE_LOCAL, você também deve definir o
hibernate.connection.provider_disables_autocommit
propriedade se o autocommit
check foi desabilitado pelo pool de conexões. Dessa forma, as conexões de banco de dados serão adquiridas lentamente antes de executar uma consulta SQL ou liberar o contexto de persistência.