Spring JPA(Hibernate) Entity Manager와의 연결 풀에 연결이 반환되는 시기는 언제입니까?
Java 프로세스에서 다음 스프링 구성을 사용하여 MySql에 연결합니다.
@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();
}
}
Entity-Manager는 컨테이너에 의해 데이터 액세스 계층에 주입됩니다.
@PersistenceContext(type = PersistenceContextType.TRANSACTION, unitName = "my-pu")
private EntityManager myEntityManager;
그리고 제 퍼블릭 비즈니스 논리 방식은 다음과 같은 주석이 달렸습니다.@Transactional 주석
내가 이해하기로는 컨테이너는 트랜잭션이 완료되면 엔티티 관리자가 풀(나의 경우 HikariCP)에 연결을 반환하도록 보장할 책임이 있지만 연결이 관리되는 방법을 설명하는 공식 문서를 찾지 못했습니다.이러한 구성을 사용할 때 정확히 언제 연결이 풀로 반환되는지 설명할 수 있는 좋은 참조 자료를 제공할 수 있는 사람이 있습니까?
업데이트:
지금까지 생각해 낸 가장 관련된 정보(여기서 발췌):
EntityManager를 구현하는 지속성 컨텍스트 프록시는 선언적 트랜잭션 관리를 수행하는 데 필요한 유일한 구성 요소가 아닙니다.실제로 세 가지 개별 구성 요소가 필요합니다.
EntityManager Proxy 자체 트랜잭션 측면 트랜잭션 관리자 각 항목을 살펴보고 이들이 어떻게 상호 작용하는지 살펴보겠습니다.
트랜잭션 측면
트랜잭션 측면은 주석이 달린 비즈니스 방법 앞과 뒤에 모두 호출되는 '주변' 측면입니다.측면을 구현하기 위한 구체적인 클래스는 트랜잭션입니다.요격기.
트랜잭션 측면에는 두 가지 주요 책임이 있습니다.
'이전' 시점에서 이 측면은 호출하려는 비즈니스 방법이 진행 중인 데이터베이스 트랜잭션의 범위에서 실행되어야 하는지 또는 새로운 별도 트랜잭션을 시작해야 하는지 여부를 결정할 수 있는 후크 포인트를 제공합니다.
'이후' 순간에는 트랜잭션을 커밋할지, 롤백할지, 계속 실행할지를 결정해야 합니다.
트랜잭션 측면 자체에 의사결정 로직이 포함되어 있지 않은 '이전' 시점에서 필요한 경우 새로운 트랜잭션을 시작하기로 한 결정은 트랜잭션 관리자에게 위임됩니다.
트랜잭션 관리자
트랜잭션 관리자는 다음 두 가지 질문에 대한 답변을 제공해야 합니다.
새 엔터티 관리자를 만들어야 합니까?새로운 데이터베이스 트랜잭션을 시작해야 합니까?이는 트랜잭션 측면의 '이전' 논리가 호출되는 순간에 결정되어야 합니다.트랜잭션 관리자는 다음을 기준으로 결정합니다.
하나의 트랜잭션이 이미 진행 중이거나 트랜잭션 메서드의 전파 속성이 아님(예: REQUEST_NEW는 항상 새 트랜잭션을 시작함) 트랜잭션 관리자가 새 트랜잭션을 만들기로 결정하면 다음과 같이 됩니다.
새 엔터티 관리자 만들기 엔터티 관리자 바인딩을 현재 스레드에 DB 연결 풀에서 연결 가져오기 엔티티 관리자와 연결은 모두 스레드로컬 변수를 사용하여 현재 스레드에 바인딩됩니다.
트랜잭션이 실행되는 동안 스레드에 저장되며, 더 이상 필요하지 않을 때 정리하는 것은 트랜잭션 관리자의 몫입니다.
현재 엔터티 관리자 또는 연결이 필요한 프로그램의 모든 부분은 스레드에서 검색할 수 있습니다.정확히 이를 수행하는 프로그램 구성 요소 중 하나가 EntityManager 프록시입니다.
전혀 복잡하지 않습니다.
첫째, Spring 트랜잭션 관리자는 트랜잭션 관리 추상화에 불과하다는 것을 이해해야 합니다.이 경우 실제 트랜잭션은 JDBC 연결 수준에서 발생합니다.
든모.
@Transactional호출은 다서메호에의가니됩로기채에 .TransactionInterceptor측면.그
TransactionIntreceptor트랜잭션 관리를 현재 구성된 구현에 위임(JpaTransactionManager당신의 경우).JpaTransactionManager현재 실행 중인 Spring 트랜잭션을 EntityManager에 바인딩하여 현재 트랜잭션에 참여하는 모든 DAO가 동일한 지속성 컨텍스트를 공유합니다.JpaTransactionManager단히사다니합을 합니다.EntityManager트랜잭션 제어를 위한 트랜잭션 API:EntityTransaction tx = txObject.getEntityManagerHolder().getEntityManager().getTransaction(); tx.commit();
JPA 트랜잭션 API는 기본 JDBC 연결 커밋/롤백 메서드에 호출을 위임합니다.
),
org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction전화 번호:transactionCoordinator().getTransactionContext().managedClose();
최대 절전 모드 세션(Entity Manager) 종료를 트리거합니다.
따라서 기본 JDBC 연결도 트리거되어 닫힙니다.
jdbcCoordinator.close();최대 절전 모드에는 논리적 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(); }다른 연결 풀링 DataSource와 마찬가지로 JDBC 연결 닫기는 단순히 연결을 풀로 되돌리고 물리적 데이터베이스 연결을 닫지 않습니다.이는 연결 풀링 DataSource가 모든 호출을 가로채는 JDBC Connection 프록시를 반환하고 연결 풀 처리 로직에 닫기를 위임하기 때문입니다.
RESOURCE_LOCAL 트랜잭션의 경우 다음과 같은 경우 속성도 설정해야 합니다.autocommit연결 풀에 의해 검사가 비활성화되었습니다.이렇게 하면 SQL 쿼리를 실행하거나 지속성 컨텍스트를 플러시하기 전에 데이터베이스 연결을 쉽게 얻을 수 있습니다.
언급URL : https://stackoverflow.com/questions/27486104/when-are-connections-returned-to-the-connection-pool-with-spring-jpa-hibernate
'programing' 카테고리의 다른 글
| Android Studio, 앱 종료 후 로그캣 청소 (0) | 2023.08.05 |
|---|---|
| ODBC 드라이버의 차이점 (0) | 2023.08.05 |
| 레일에서 Ajax 호출의 성공 또는 실패를 간단히 반환 (0) | 2023.08.05 |
| 외부 장치에서 로컬로 Laravel 5 앱에 액세스 (0) | 2023.08.05 |
| Alpine 리눅스 기반 오라클 (0) | 2023.08.05 |