Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Wann werden Verbindungen mit Spring JPA (Hibernate) Entity Manager an den Verbindungspool zurückgegeben?

Es ist überhaupt nicht kompliziert.

  1. Zunächst müssen Sie verstehen, dass der Spring-Transaktionsmanager nur eine Transaktionsverwaltungsabstraktion ist. In Ihrem Fall finden die eigentlichen Transaktionen auf der JDBC-Verbindungsebene statt.

  2. Alle @Transactional Dienstmethodenaufrufe werden vom TransactionInterceptor abgefangen Aspekt.

  3. Der TransactionIntreceptor delegiert die Transaktionsverwaltung an den aktuell konfigurierten AbstractPlatformTransactionManager Implementierung (JpaTransactionManager in Ihrem Fall).

  4. JpaTransactionManager bindet die aktuell laufende Spring-Transaktion an einen EntityManager, sodass alle DAOs, die an der aktuellen Transaktion teilnehmen, denselben Persistenzkontext teilen.

  5. JpaTransactionManager verwendet einfach den EntityManager Transaktions-API zur Steuerung von Transaktionen:

     EntityTransaction tx = txObject.getEntityManagerHolder().getEntityManager().getTransaction();
     tx.commit();
    

Die JPA-Transaktions-API delegiert den Aufruf einfach an die zugrunde liegenden Commit-/Rollback-Methoden der JDBC-Verbindung.

  1. Wenn die Transaktion abgeschlossen ist (commit/rollback), wird die org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction Aufrufe:

     transactionCoordinator().getTransactionContext().managedClose();
    

was das Schließen einer Hibernate Session (Entity Manager) auslöst.

  1. Das Schließen der zugrunde liegenden JDBC-Verbindung wird daher ebenfalls ausgelöst:

     jdbcCoordinator.close();
    
  2. Hibernate hat ein logisches JDBC-Verbindungshandle:

     @Override
     public Connection close() {
         LOG.tracev( "Closing JDBC container [{0}]", this );
         if ( currentBatch != null ) {
         LOG.closingUnreleasedBatch();
             currentBatch.release();
         }
         cleanup();
         return logicalConnection.close();
     }
    
  3. Die logische Verbindung delegiert den Close-Aufruf an den aktuell konfigurierten Verbindungsanbieter (DataSourceConnectionProvider in Ihrem Fall), die einfach die close-Methode für die JDBC-Verbindung aufruft:

     @Override
     public void closeConnection(Connection connection) throws SQLException {
          connection.close();
     }
    
  4. Wie bei jeder anderen Datenquelle für das Verbindungspooling gibt das Schließen der JDBC-Verbindung einfach die Verbindung zum Pool zurück und schließt nicht die physische Datenbankverbindung. Das liegt daran, dass die Datenquelle für das Verbindungspooling einen JDBC-Verbindungsproxy zurückgibt, der alle Aufrufe abfängt und das Schließen an die Verarbeitungslogik für den Verbindungspool delegiert.

Beachten Sie, dass Sie für RESOURCE_LOCAL-Transaktionen auch hibernate.connection.provider_disables_autocommit -Eigenschaft, wenn die autocommit check wurde vom Verbindungspool deaktiviert. Auf diese Weise werden die Datenbankverbindungen träge erfasst, bevor eine SQL-Abfrage ausgeführt oder der Persistenzkontext geleert wird.