Det är inte alls komplicerat.
-
Först måste du förstå att Spring-transaktionshanteraren bara är en abstraktion av transaktionshantering. I ditt fall sker de faktiska transaktionerna på JDBC-anslutningsnivån.
-
Alla
@Transactional
servicemetodsamtal fångas upp avTransactionInterceptor
Aspekt. -
TransactionIntreceptor
delegerar transaktionshantering till den nuvarande konfigureradeAbstractPlatformTransactionManager
implementering (JpaTransactionManager
i ditt fall). -
JpaTransactionManager
kommer att binda den aktuella Spring-transaktionen till en EntityManager, så att alla DAO:er som deltar i den aktuella transaktionen delar samma Persistence Context. -
JpaTransactionManager
använder helt enkeltEntityManager
Transaktions-API för att kontrollera transaktioner:EntityTransaction tx = txObject.getEntityManagerHolder().getEntityManager().getTransaction(); tx.commit();
JPA Transaction API delegerar helt enkelt anropet till de underliggande JDBC Connection commit/back-metoderna.
-
När transaktionen är klar (commit/rollback) visas
org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction
samtal:transactionCoordinator().getTransactionContext().managedClose();
som utlöser en vilolägessession (Entity Manager) stängning.
-
Den underliggande JDBC-anslutningen utlöses därför att också stängas:
jdbcCoordinator.close();
-
Hibernate har ett logiskt JDBC-anslutningshandtag:
@Override public Connection close() { LOG.tracev( "Closing JDBC container [{0}]", this ); if ( currentBatch != null ) { LOG.closingUnreleasedBatch(); currentBatch.release(); } cleanup(); return logicalConnection.close(); }
-
Den logiska anslutningen delegerar det avslutande samtalet till den för närvarande konfigurerade anslutningsleverantören (
DataSourceConnectionProvider
i ditt fall), som helt enkelt anropar stängningsmetoden på JDBC-anslutningen:@Override public void closeConnection(Connection connection) throws SQLException { connection.close(); }
-
Som alla andra anslutningar som poolar DataSource, returnerar JDBC-anslutningen helt enkelt anslutningen till poolen och stänger inte den fysiska databasanslutningen. Det beror på att anslutningspoolen DataSource returnerar en JDBC Connection proxy som fångar upp alla samtal och delegerar stängningen till logiken för hantering av anslutningspoolen.
Observera att för RESOURCE_LOCAL-transaktioner bör du också ställa in hibernate.connection.provider_disables_autocommit
egenskapen om autocommit
kontrollen inaktiverades av anslutningspoolen. På så sätt kommer databasanslutningarna att förvärvas lätt innan en SQL-fråga körs eller persistenskontexten töms.