Изобщо не е сложно.
-
Първо, трябва да разберете, че мениджърът на транзакции Spring е само абстракция за управление на транзакции. Във вашия случай действителните транзакции се случват на ниво JDBC Connection.
-
Всички
@Transactionalизвикванията на метод на услугата се прихващат отTransactionInterceptorАспект. -
TransactionIntreceptorделегира управлението на транзакциите на текущия конфигуриранAbstractPlatformTransactionManagerреализация (JpaTransactionManagerвъв вашия случай). -
JpaTransactionManagerще свърже текущата текуща транзакция Spring към EntityManager, така че всички DAO, участващи в текущата транзакция, споделят един и същ контекст на постоянство. -
JpaTransactionManagerпросто използваEntityManagerAPI за транзакции за контролиране на транзакции:EntityTransaction tx = txObject.getEntityManagerHolder().getEntityManager().getTransaction(); tx.commit();
JPA Transaction API просто делегира извикването към основните методи за записване/връщане на JDBC връзка.
-
Когато транзакцията е извършена (commit/rollback),
org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionобаждания:transactionCoordinator().getTransactionContext().managedClose();
което задейства затваряне на сесия в хибернация (Entity Manager).
-
Следователно основната JDBC връзка също се задейства, за да бъде затворена:
jdbcCoordinator.close(); -
Hibernate има логическа дръжка за JDBC връзка:
@Override public Connection close() { LOG.tracev( "Closing JDBC container [{0}]", this ); if ( currentBatch != null ) { LOG.closingUnreleasedBatch(); currentBatch.release(); } cleanup(); return logicalConnection.close(); } -
Логическата връзка делегира извикването за затваряне към текущо конфигурирания доставчик на връзка (
DataSourceConnectionProviderвъв вашия случай), който просто извиква метода за затваряне на JDBC връзката:@Override public void closeConnection(Connection connection) throws SQLException { connection.close(); } -
Както всеки друг източник на данни за обединяване на връзки, затварянето на JDBC връзката просто връща връзката към пула и не затваря физическата връзка с базата данни. Това е така, защото DataSource за събиране на връзки връща прокси JDBC Connection, който прихваща всички повиквания и делегира затварянето на логиката за обработка на пула за връзки.
Имайте предвид, че за транзакции RESOURCE_LOCAL трябва също да зададете hibernate.connection.provider_disables_autocommit
свойство, ако autocommit проверката беше деактивирана от пула за връзки. По този начин връзките към базата данни ще бъдат придобити мързеливо, преди да се изпълни SQL заявка или да се прочисти контекста на постоянство.