首页 文章

Spring JDBC连接池的最佳实践

提问于
浏览
36

我有一个基本的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上有更多学分的图书馆是CP30DBCP . 由于我使用的是Oracle,我也可以使用驱动程序提供的pooled data source . 我知道有更多的库可用 - 例如新的Apache Tomcat 7池库 .

有没有我应该避免的图书馆?

我应该在给定的库中使用任何推荐的配置吗?

你想分享的任何“战争故事”?

4 回答

  • 17

    C3PO和DBCP的发展已停滞不前,主要是因为它们已经成熟 . 我已经看到这两个驱动程序每秒能够支持数百个事务 .

    Tomcat池是一个经过重新设计和更新的DBCP驱动程序 . MyBatis 3.0还包含它's own pooling implementation which, based on code inspection, seems solid. Finally, there' s BoneCP,声称具有最佳性能 . 我还没有在项目中使用过这些 .

    可能最好的建议是选择其中任何一个进行测试 . Spring可以让以后轻松换出 .

  • 20

    作为BoneCP的替代方案,您是否尝试过Oracle自己的数据库连接池?

    我在过去的几个星期里有过很好的经历,所以值得一试 - 同样,我想Oracle会知道关于创建连接池的一两件事,特别是在与自己的数据库配对时 .

    <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>
    

    UPDATE :此外,如果您正在使用(最新的)一个Oracle JDBC驱动程序(11.2.0.1),您可能需要尝试新的通用连接池 . OracleConnectionPoolDataSource 似乎已被正式弃用,以支持此池 . 但是,有些用户报告使用它时出错,所以可能为时尚早 . 我可以使用Oracle的最新JDBC驱动程序,所以我会尽快给它一个更新,并在此有任何信息 .

    有关此SO线程的更多信息:Oracle UCP

  • 9

    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
    

    要获得正确的演示,您可以使用this link

  • 0

    绝对可以使用C3P0,这是为企业解决方案而开发的 . 要检查优势,您可以follow this answer .

    Here is the example code of integration:

    @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 . 它从 hibProperties() 获取 DataSourcePersistenceProviderClass ,实体包名 PackagesToScan 和JpaProperties .

    @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 value are comming from application.properties .

    检查波纹管属性:

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

    The main part is DataSource Setup. That is given bellow

    @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;
        }
    

    它正在使用 ComboPooledDataSource ,它正在采用更多重要参数,如maxPoolSize,MinPoolSize,MaxIdleSize等. It's environment parameter are given bellow:

    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
    

    Here is the full working sample code:

    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'
    

    希望这会帮助你 . 谢谢 :)

相关问题