Det er slet ikke kompliceret.
-
Først skal du forstå, at Spring-transaktionsmanageren kun er en abstraktion af transaktionsstyring. I dit tilfælde sker de faktiske transaktioner på JDBC-forbindelsesniveau.
-
Alle
@Transactional
servicemetodekald opfanges afTransactionInterceptor
Aspekt. -
TransactionIntreceptor
uddelegerer transaktionsstyring til den nuværende konfigureredeAbstractPlatformTransactionManager
implementering (JpaTransactionManager
i dit tilfælde). -
JpaTransactionManager
vil binde den aktuelle kørende Spring-transaktion til en EntityManager, så alle DAO'er, der deltager i den aktuelle transaktion, deler den samme Persistence Context. -
JpaTransactionManager
bruger blotEntityManager
Transaktions-API til styring af transaktioner:EntityTransaction tx =txObject.getEntityManagerHolder().getEntityManager().getTransaction(); tx.commit();
JPA Transaction API delegerer simpelthen opkaldet til de underliggende JDBC Connection commit/rollback metoder.
-
Når transaktionen er gennemført (commit/rollback), er
org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction
opkald:transactionCoordinator().getTransactionContext().managedClose();
som udløser en dvale-session (Entity Manager)-lukning.
-
Den underliggende JDBC-forbindelse udløses derfor også til at blive lukket:
jdbcCoordinator.close();
-
Hibernate har et logisk JDBC-forbindelseshåndtag:
@Override public Connection close() { LOG.tracev( "Lukker JDBC container [{0}]", denne); if ( currentBatch !=null ) { LOG.closingUnreleasedBatch(); currentBatch.release(); } Ryd op(); returner logicalConnection.close(); }
-
Den logiske forbindelse uddelegerer det lukkede opkald til den aktuelt konfigurerede forbindelsesudbyder (
DataSourceConnectionProvider
i dit tilfælde), som blot kalder lukkemetoden på JDBC-forbindelsen:@Override public void closeConnection(Connection connection) kaster SQLException { connection.close(); }
-
Som enhver anden forbindelse, der samler DataSource, returnerer JDBC-forbindelsen blot forbindelsen til poolen og lukker ikke den fysiske databaseforbindelse. Det skyldes, at forbindelsespooling DataSource returnerer en JDBC Connection proxy, der opsnapper alle opkald og delegerer lukningen til forbindelsespuljens håndteringslogik.
Bemærk, at for RESOURCE_LOCAL-transaktioner skal du også indstille hibernate.connection.provider_disables_autocommit
egenskaben, hvis autocommit
check blev deaktiveret af forbindelsespuljen. På denne måde vil databaseforbindelserne blive erhvervet dovent før udførelse af en SQL-forespørgsel eller fjernelse af persistenskonteksten.