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@Transactionalchamadas de métodos de serviço são interceptadas peloTransactionInterceptorAspecto.
-
OTransactionIntreceptordelega o gerenciamento de transações para oAbstractPlatformTransactionManagerimplementação (JpaTransactionManagerno seu caso).
-
JpaTransactionManagervinculará 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.
-
JpaTransactionManagersimplesmente usa oEntityManagerAPI 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.JdbcTransactionchamadas:
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 (DataSourceConnectionProviderno 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.