Wenn eine Verbindung an den Verbindungspool zurückgegeben mit Spring JPA (Hibernate) Entity-Manager?

In meinem java-Prozess, ich bin die Verbindung zu MySql mit den folgenden Frühjahr-Konfiguration:

@Configuration
@EnableTransactionManagement
@PropertySources({ @PropertySource("classpath:/myProperties1.properties"), @PropertySource("classpath:/myProperties2.properties") })
public class MyConfiguration {

    @Autowired
    protected Environment env;

    /**
     * @return EntityManagerFactory for use with Hibernate JPA provider
     */
    @Bean(destroyMethod = "destroy")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
    LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
    em.setDataSource(dataSource());
    em.setJpaVendorAdapter(jpaVendorAdapter());
    em.setPersistenceUnitManager(persistenceUnitManager());

    return em;
    }

    /**
     * 
     * @return jpaVendorAdapter that works in conjunction with the
     *         persistence.xml
     */
    @Bean
    public JpaVendorAdapter jpaVendorAdapter() {
    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    vendorAdapter.setDatabase(Database.valueOf(env.getProperty("jpa.database")));
    vendorAdapter.setDatabasePlatform(env.getProperty("jpa.dialect"));
    vendorAdapter.setGenerateDdl(env.getProperty("jpa.generateDdl", Boolean.class, false));
    vendorAdapter.setShowSql(env.getProperty("jpa.showSql", Boolean.class, false));

    return vendorAdapter;
    }

    @Bean
    public PersistenceUnitManager persistenceUnitManager() {
    DefaultPersistenceUnitManager pum = new DefaultPersistenceUnitManager();
    pum.setPackagesToScan("com.app.dal");
    pum.setDefaultPersistenceUnitName("my-pu");
    pum.setPersistenceXmlLocations("classpath:/META-INF/persistence.xml");
    pum.setDefaultDataSource(dataSource());

    return pum;
    }

    @Bean(destroyMethod = "close")
    public DataSource dataSource() {
    Properties dsProps = new Properties();
    dsProps.put("driverClassName", env.getProperty("hikari.driverClassName"));
    dsProps.put("username", env.getProperty("hikari.username"));
    dsProps.put("password", env.getProperty("hikari.password"));
    dsProps.put("jdbcUrl", env.getProperty("hikari.source.data.jdbcUrl"));
    dsProps.put("connectionTimeout", env.getProperty("hikari.connectionTimeout", Integer.class));
    dsProps.put("idleTimeout", env.getProperty("hikari.idleTimeout", Integer.class));
    dsProps.put("maxLifetime", env.getProperty("hikari.maxLifetime", Integer.class));
    dsProps.put("maximumPoolSize", env.getProperty("hikari.maximumPoolSize.rtb.source", Integer.class));
    dsProps.put("leakDetectionThreshold", env.getProperty("hikari.leakDetectionThreshold", Integer.class));
    dsProps.put("jdbc4ConnectionTest", env.getProperty("hikari.jdbc4ConnectionTest", Boolean.class));

    HikariConfig config = new HikariConfig(dsProps);
    HikariDataSource ds = new HikariDataSource(config);

    return ds;
    }

    @Bean(name = "sourceTxMgr")
    public PlatformTransactionManager sourceDatatransactionManager() {
    JpaTransactionManager transactionManager = new JpaTransactionManager();
    transactionManager.setPersistenceUnitName("my-pu");
    transactionManager.setDataSource(dataSource());

    return transactionManager;
    }

    @Bean
    public PersistencyManager persistencyManager() {
    return new JpaPersistencyManager();
    }

    @Bean
    public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
    return new PersistenceExceptionTranslationPostProcessor();
    }

}

Den Entity-Manager wird injiziert, um die data access layer durch den container:

@PersistenceContext(type = PersistenceContextType.TRANSACTION, unitName = "my-pu")
private EntityManager myEntityManager;

Und meine öffentliche business-logic-Methoden sind gekennzeichnet mit der @Transactional annotation.

Soweit ich das verstanden habe der container ist dafür verantwortlich, dass der entity-manager gibt verbindungen zu dem pool (in meinem Fall HikariCP) sobald eine Transaktion ist getan aber ich habe keine offizielle Dokumentation, die beschreibt, wie die verbindungen verwaltet werden. Kann jemand es mir erklären oder eine gute Referenz, die erklären können, Wann genau die verbindungen werden an den pool zurückgegeben, wenn mit einer solchen Konfiguration?

UPDATE:

Die besten Informationen konnte ich kommen mit so weit (hier):

Den Persistenz-Kontext-proxy implementiert, mit der EntityManager ist nicht die einzige Komponente benötigt für die Herstellung der deklarativen Transaktions-management arbeiten. Eigentlich drei separate Komponenten werden benötigt:

Den EntityManager-Proxy selbst
Der Transaktionale Aspekt
Der Transaktions-Manager
Wir gehen über jedes und sehen, wie Sie interagieren.

Den Transaktionalen Aspekt

Den Transaktionalen Aspekt ist ein " um " Aspekt, der aufgerufen wird, sowohl vor als auch nach der kommentierten business-Methode. Die konkrete Klasse für die Umsetzung der Aspekt ist TransactionInterceptor.

Den Transaktionalen Aspekt hat zwei Hauptaufgaben:

In der 'vor' - moment, den Aspekt stellt einen hook-Punkt für die Bestimmung, falls die business-Methode etwa genannt zu werden, soll die Ausführung im Rahmen einer Laufenden Datenbank-Transaktion, oder wenn eine neue eigene Transaktion gestartet werden soll.

In die 'nach' - moment, der Aspekt muss entscheiden, ob die Transaktion soll verpflichtet werden, ein Rollback oder Links laufen.

In der 'vor' - moment, der Transaktionale Aspekt selbst enthält keine Entscheidung, die Logik, die Entscheidung zum starten einer neuen Transaktion, wenn erforderlich, delegiert an den Transaktions-Manager.

Transaction Manager

Wird der Transaktions-manager muss eine Antwort auf zwei Fragen:

sollte eine neue Entity Manager erstellt werden?
sollten Sie eine neue Datenbank-Transaktion gestartet werden?
Dies muss entschieden werden, im moment ist der Transaktionale Aspekt " vor " - Logik genannt wird. Der Transaktions-manager entscheidet:

die Tatsache, dass eine Transaktion ist die bereits Laufenden oder nicht
die Ausbreitung Attribut der Transaktions-Methode (zum Beispiel REQUIRES_NEW beginnt immer eine neue Transaktion)
Wenn der Transaktions-manager beschließt, eine neue Transaktion, dann wird es:

erstellen einer neuen entity manager
binden Sie das entity manager auf den aktuellen thread
schnappen Sie sich eine Verbindung von der DB-Verbindungs-pool
binden Sie die Verbindung zu den aktuellen thread
Der entity-manager und die Verbindung sind sowohl die gebundenen als auch den aktuellen thread mit ThreadLocal Variablen.

Diese gespeichert sind in dem thread, während die Transaktion ausgeführt wird, und es ist bis zu den Transaktions-Manager, um Sie zu reinigen, wenn nicht mehr benötigt.

Teile des Programms, die aktuelle entity-manager oder-Verbindung abrufen kann aus dem thread. Eine Programm-Komponente, die genau das tut, der ist der EntityManager-proxy.

  • Ich bezweifle, dass der container ist verantwortlich für die Rückkehr verbindungen. Es ist Frühling, und das ist verantwortlich, da es die Verwaltung der Transaktionen durch die JPATransactionManager. Ein guter Weg, um zu bestätigen, wäre zum aktivieren der Frühling und der HikariCP Protokolle, und bestätigen Sie es.
  • Wenn ich sage "Der container" - ich spring container, oder um genauer zu sein in der Entity-Manager verwaltet von spring-container. docs.Frühling.io/spring/docs/current/spring-framework-reference/...
  • Die website, die Sie gemeinsam nach unten. Können Sie die Verknüpfung aktualisieren.
InformationsquelleAutor forhas | 2014-12-15
Schreibe einen Kommentar