복붙노트

[SPRING] Spring JDBC 연결 풀 모범 사례

SPRING

Spring JDBC 연결 풀 모범 사례

꽤 기본적인 설정으로 기본적인 Spring JDBC 애플리케이션을 가지고있다 :

<bean id="myDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
   <property name="driverClassName" value="oracle.jdbc.OracleDriver"/>
   <property name="url" value="jdbc:oracle:thin:@1.1.1.1:1521:XXX"/>
   <property name="username" value="username"/>
   <property name="password" value="password"/>
</bean>

<bean id="dbThing" class="com.DbThing">
   <property name="dataSource" ref="myDataSource"/>
</bean>

연결 풀을 소개하고 싶습니다. 그래서 여기에 여러 스레드를 읽은 후에 사용할 풀링 라이브러리에 대해 약간 혼란스러워합니다.

SO에 더 많은 크레디트를 가진 라이브러리는 CP30 및 DBCP입니다. Oracle을 사용하고 있기 때문에 드라이버가 제공하는 풀링 된 데이터 소스를 사용할 수도 있습니다. 사용할 수있는 라이브러리가 더 많다는 것을 알고 있습니다. 예를 들어 새로운 Apache Tomcat 7 풀링 라이브러리가 있습니다.

내가 정말로 피해야하는 도서관이 있습니까?

주어진 라이브러리와 함께 사용해야하는 권장 구성이 있습니까?

당신이 공유하는 모든 "전쟁 이야기"?

해결법

  1. ==============================

    1.C3PO와 DBCP 개발은 성숙기 때문에 대부분 멈췄습니다. 나는이 두 드라이버가 초당 수백 건의 트랜잭션을 지원할 수 있음을 보았습니다.

    C3PO와 DBCP 개발은 성숙기 때문에 대부분 멈췄습니다. 나는이 두 드라이버가 초당 수백 건의 트랜잭션을 지원할 수 있음을 보았습니다.

    Tomcat 풀은 다시 제작되고 업데이트 된 DBCP 드라이버입니다. MyBatis 3.0에는 코드 검사를 기반으로하는 자체 풀링 구현이 포함되어 있습니다. 마지막으로 BoneCP가 최고의 성능을 발휘한다고 주장합니다. 나는 이들 중 어느 것도 아직 프로젝트에 사용하지 않았다.

    아마도 가장 좋은 충고는 그들 중 누구라도 시험 해보는 것입니다. Spring을 사용하면 나중에 쉽게 바꿀 수 있습니다.

  2. ==============================

    2.BoneCP의 대안으로 Oracle의 데이터베이스 연결 풀을 사용해 보셨습니까?

    BoneCP의 대안으로 Oracle의 데이터베이스 연결 풀을 사용해 보셨습니까?

    저는 지난 2 주 동안 좋은 경험을 했으므로 한 번 시도해 볼만한 가치가 있습니다. 오라클은 특히 자신의 데이터베이스와 연결될 때 연결 풀을 만드는 것에 대해 두세 가지를 알고 있다고 생각합니다.

    <bean id="dataSource" class="oracle.jdbc.pool.OracleConnectionPoolDataSource">
        <property name="URL" value="${jdbc.url}" />
        <property name="user" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    </bean>
    

    업데이트 : 또한 최신 Oracle JDBC 드라이버 (11.2.0.1 이상) 중 하나를 사용하는 경우 새로운 범용 연결 풀을 사용해 볼 수도 있습니다. OracleConnectionPoolDataSource는 공식적으로이 풀을 사용하도록 권장되지 않습니다. 그러나 일부 사용자는이 오류를 사용하여 오류를보고하므로 너무 일찍 올 수 있습니다. 필자는 Oracle의 최신 JDBC 드라이버를 사용할 수있는 위치에 있으므로이 정보를 얻 자마자 여기에서 시도하고 업데이트 할 것입니다.

    이 SO 스레드에 대한 자세한 정보 : Oracle UCP

  3. ==============================

    3.BoneCP는 주장했지만 HiKariCP라는 이름의 새로운 도구가 소개되었습니다.이 도구는 application-context.xml에서 아래와 같이 변경할 수있는 패스 도구에있는 많은 단점을 극복했습니다.

    BoneCP는 주장했지만 HiKariCP라는 이름의 새로운 도구가 소개되었습니다.이 도구는 application-context.xml에서 아래와 같이 변경할 수있는 패스 도구에있는 많은 단점을 극복했습니다.

    <bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
      <property name="maximumPoolSize" value="10" />
      <property name="minimumPoolSize" value="2" />
      <property name="dataSourceClassName" 
                value="oracle.jdbc.pool.OracleDataSource" />
      <property name="dataSourceProperties" ref="props" />
      <property name="poolName" value="springHikariCP" />
    </bean>
    
    <bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
          <constructor-arg ref="hikariConfig" />
    </bean>
    
    <util:properties id="props" location="classpath:datasource.properties"/>
    

    database.properties에서 다음과 같은 데이터베이스의 세부 정보를 제공해야합니다.

     url=jdbc:oracle:thin:@IP:port:SID/Databasename
     user=usernmae
     password=password
    

    적절한 데모를 보려면이 링크를 사용하십시오.

  4. ==============================

    4.확실히 C3P0을 사용할 수 있습니다.이 솔루션은 엔터프라이즈 솔루션 용으로 개발되었습니다. 이점을 확인하려면이 대답을 따를 수 있습니다.

    확실히 C3P0을 사용할 수 있습니다.이 솔루션은 엔터프라이즈 솔루션 용으로 개발되었습니다. 이점을 확인하려면이 대답을 따를 수 있습니다.

    다음은 통합 예제 코드입니다.

    @Bean
        public JpaTransactionManager transactionManager() {
            JpaTransactionManager transactionManager =
                    new JpaTransactionManager();
            transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
            return transactionManager;
        }
    

    이 Bean은 JpaTransactionManager를 가져 오는 것입니다.

    @Primary
    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
    
        LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
        entityManagerFactoryBean.setDataSource(dataSource());
        entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class);
        entityManagerFactoryBean.setPackagesToScan("YOUR.DATABSE.ENTITY.PACKAGE");
        entityManagerFactoryBean.setJpaProperties(hibProperties());
    
        return entityManagerFactoryBean;
    }
    

    이 Bean은 LocalContainerEntityManagerFactoryBean을 가져 오는 데 사용됩니다. DataSource, PersistenceProviderClass, 엔티티 패키지 이름 PackagesToScan 및 JpaProperties를 hibProperties ()에서 가져옵니다.

    @Bean
        public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
            return new PersistenceExceptionTranslationPostProcessor();
        }
    
    private Properties hibProperties() {
            Properties properties = new Properties();
            properties.put("hibernate.dialect", env.getProperty("hibernate.dialect"));
            properties.put("hibernate.show_sql", env.getProperty("hibernate.show_sql"));
            properties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
            return properties;
        }
    

    여기에서 env 값은 application.properties에서옵니다.

    벨로우즈 속성 확인 :

    hibernate.dialect: org.hibernate.dialect.Oracle12cDialect
    hibernate.show_sql: false
    hibernate.hbm2ddl.auto: none
    

    주요 부분은 데이터 소스 설정입니다. 그것은 아래에 주어진다 :

    @Bean
        public ComboPooledDataSource dataSource(){
            ComboPooledDataSource dataSource = new ComboPooledDataSource();
    
            try {
                dataSource.setDriverClass(env.getProperty("db.driver"));
                dataSource.setJdbcUrl(env.getProperty("db.url"));
                dataSource.setUser(env.getProperty("db.username"));
                dataSource.setPassword(env.getProperty("db.password"));
                dataSource.setMinPoolSize(Integer.parseInt(env.getProperty("minPoolSize")));
                dataSource.setMaxPoolSize(Integer.parseInt(env.getProperty("maxPoolSize")));
                dataSource.setMaxIdleTime(Integer.parseInt(env.getProperty("maxIdleTime")));
                dataSource.setMaxStatements(Integer.parseInt(env.getProperty("maxStatements")));
                dataSource.setMaxStatementsPerConnection(Integer.parseInt(env.getProperty("maxStatementsPerConnection")));
                dataSource.setMaxIdleTimeExcessConnections(10000);
    
            } catch (PropertyVetoException e) {
                e.printStackTrace();
            }
            return dataSource;
        }
    

    maxPoolSize, MinPoolSize, MaxIdleSize 등의보다 중요한 매개 변수를 사용하는 ComboPooledDataSource를 사용하고 있습니다. 환경 변수는 다음과 같습니다.

    db.driver: oracle.jdbc.driver.OracleDriver // for Oracle
    db.username: YOUR_USER_NAME
    db.password: YOUR_USER_PASSWORD
    db.url: DATABASE_URL
    minPoolSize:5 // number of minimum poolSize
    maxPoolSize:100 // number of maximum poolSize
    maxIdleTime:5 // In seconds. After that time it will realease the unused connection.
    maxStatements:1000
    maxStatementsPerConnection:100
    maxIdleTimeExcessConnections:10000
    

    전체 작동 샘플 코드는 다음과 같습니다.

    import com.mchange.v2.c3p0.ComboPooledDataSource;
    import org.hibernate.jpa.HibernatePersistenceProvider;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.context.annotation.*;
    import org.springframework.core.env.Environment;
    import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
    import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
    import org.springframework.orm.jpa.JpaTransactionManager;
    import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
    import org.springframework.transaction.annotation.EnableTransactionManagement;
    
    import javax.sql.DataSource;
    import java.beans.PropertyVetoException;
    import java.util.Properties;
    
    @Configuration
    @EnableTransactionManagement
    @EnableJpaRepositories
    @PropertySource("classpath:application.properties")
    @Scope("singleton")
    public class TestDataSource {
    
        @Autowired
        private Environment env;
    
        @Qualifier("dataSource")
        @Autowired
        private DataSource dataSource;
    
        @Bean
        public JpaTransactionManager transactionManager() {
            JpaTransactionManager transactionManager =
                    new JpaTransactionManager();
            transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
            return transactionManager;
        }
    
        @Primary
        @Bean
        public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
    
            LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
            entityManagerFactoryBean.setDataSource(dataSource());
            entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class);
            entityManagerFactoryBean.setPackagesToScan("YOUR.PACKAGE.NAME");
            entityManagerFactoryBean.setJpaProperties(hibProperties());
    
            return entityManagerFactoryBean;
        }
    
        @Bean
        public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
            return new PersistenceExceptionTranslationPostProcessor();
        }
    
        @Bean
        public ComboPooledDataSource dataSource(){
            ComboPooledDataSource dataSource = new ComboPooledDataSource();
    
            try {
                dataSource.setDriverClass(env.getProperty("db.driver"));
                dataSource.setJdbcUrl(env.getProperty("db.url"));
                dataSource.setUser(env.getProperty("db.username"));
                dataSource.setPassword(env.getProperty("db.password"));
                dataSource.setMinPoolSize(Integer.parseInt(env.getProperty("minPoolSize")));
                dataSource.setMaxPoolSize(Integer.parseInt(env.getProperty("maxPoolSize")));
                dataSource.setMaxIdleTime(Integer.parseInt(env.getProperty("maxIdleTime")));
                dataSource.setMaxStatements(Integer.parseInt(env.getProperty("maxStatements")));
                dataSource.setMaxStatementsPerConnection(Integer.parseInt(env.getProperty("maxStatementsPerConnection")));
                dataSource.setMaxIdleTimeExcessConnections(10000);
    
            } catch (PropertyVetoException e) {
                e.printStackTrace();
            }
            return dataSource;
        }
    
        private Properties hibProperties() {
            Properties properties = new Properties();
            properties.put("hibernate.dialect", env.getProperty("hibernate.dialect"));
            properties.put("hibernate.show_sql", env.getProperty("hibernate.show_sql"));
            properties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
            return properties;
        }
    }
    

    다른 것. 여기는 gradle 링크입니다

    compile group: 'org.hibernate', name: 'hibernate-c3p0', version: '5.2.10.Final'
    

    희망이 당신을 도울 것입니다. 감사 :)

  5. from https://stackoverflow.com/questions/5117191/spring-jdbc-connection-pool-best-practices by cc-by-sa and MIT license