В моем процессе Java Я подключения к MySql, используя следующую конфигурацию пружины:Когда соединения возвращаются в пул подключений с помощью диспетчера сущностей Spring JPA (Hibernate)?
@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();
}
}
субъект-менеджер впрыскивается в слой доступа к данным с помощью контейнера:
@PersistenceContext(type = PersistenceContextType.TRANSACTION, unitName = "my-pu")
private EntityManager myEntityManager;
И мой общедоступный методы бизнес-логики аннотируются с аннотацией @Transactional
.
Насколько я понимаю, контейнер несет ответственность за то, что объект-менеджер возвращает соединения с пулом (в моем случае HikariCP) после выполнения транзакции, но я не нашел официальную документацию, описывающую, как соединения удалось. Может ли кто-нибудь объяснить это мне или предоставить хорошую ссылку, которая может объяснить, когда именно соединения возвращаются в пул при использовании такой конфигурации?
UPDATE:
Лучшая родственная информацию я мог придумать до сих пор (taken from here):
Сохранения контекста прокси, который реализует EntityManager не единственный компонент, необходимый для создания декларативной работы управления транзакциями , На самом деле необходимы три отдельных компонента:
Сам Транзакционная Аспект Менеджер транзакций Давайте рассмотрим каждый из них и посмотреть, как они взаимодействуют EntityManager Proxy.
Транзакционная Аспект
Транзакционная аспект является «вокруг» аспект, который вызывается до и после аннотированных методов бизнеса. Конкретным классом для реализации аспекта является TransactionInterceptor.
Транзакционная аспект имеет две основные функции:
В «до» момент, аспект обеспечивает точку крюка для определения, если бизнес метод собирается назвать должен работать в рамках текущей транзакции базы данных, или если необходимо начать новую отдельную транзакцию.
В момент «после» аспект должен решить, следует ли совершить транзакцию, откат или оставление на ходу.
В момент «до» сам Transactional Aspect не содержит логики решения, решение о начале новой транзакции при необходимости делегируется диспетчеру транзакций.
Сделка менеджер
Сделка менеджер должен дать ответ на два вопроса:
должен быть создан новый менеджер Entity? Следует ли начать новую транзакцию базы данных? Это необходимо решить в тот момент, когда вызывается логика Transactional Aspect 'before'.Менеджер транзакций будет принимать решение на основании:
тот факт, что одна транзакция уже продолжается или не устанавливается атрибут распространения транзакционного метода (например REQUIRES_NEW всегда начинает новую транзакцию) Если менеджер транзакций решает создать новый сделка, то это будет:
создать новый диспетчер сущностей связать менеджер сущности к текущей нити захватить соединение из пула соединений DB привязывания к текущему потоку диспетчера объектов и связи являются связанные с текущим потоком с использованием переменных ThreadLocal.
Они хранятся в потоке во время выполнения транзакции, и Менеджер транзакций должен очистить их, когда они больше не нужны.
Любые части программы, которым нужен текущий менеджер или соединение с узлом, могут извлекать их из потока. Один программный компонент, который выполняет именно это прокси-сервер EntityManager.
Сомневаюсь, что контейнер отвечает за возврат соединений. Это Spring, которая отвечает за управление транзакциями через JPATransactionManager. Хорошим способом подтверждения было бы включить весну и журналы HikariCP и проверить ее. –
Когда я говорю «Контейнер», я весенний контейнер, или, если быть более конкретным, Entity-Manager, которым управляет пружинный контейнер. http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html – forhas