Изобщо не е сложно.
-
Първо, трябва да разберете, че мениджърът на транзакции Spring е само абстракция за управление на транзакции. Във вашия случай действителните транзакции се случват на ниво JDBC Connection.
-
Всички
@Transactional
извикванията на метод на услугата се прихващат отTransactionInterceptor
Аспект. -
TransactionIntreceptor
делегира управлението на транзакциите на текущия конфигуриранAbstractPlatformTransactionManager
реализация (JpaTransactionManager
във вашия случай). -
JpaTransactionManager
ще свърже текущата текуща транзакция Spring към EntityManager, така че всички DAO, участващи в текущата транзакция, споделят един и същ контекст на постоянство. -
JpaTransactionManager
просто използваEntityManager
API за транзакции за контролиране на транзакции: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 заявка или да се прочисти контекста на постоянство.