推荐的连接池

Java应用推荐使用DBCP。

Java代码实例:

public BasicDataSource rdsDataSource() {
        BasicDataSource ds = new BasicDataSource();
        ds.setUrl(rdsUrl);
        ds.setUsername(userName);
        ds.setPassword(passWord);
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setInitialSize(initialSize);
        ds.setMaxActive(maxActive);
        ds.setMaxIdle(maxActive - 5);
        ds.setMaxWait(maxWait);
        ds.setPoolPreparedStatements(false);
        ds.setDefaultAutoCommit(true);

        ds.setValidationQuery("select 1");
        ds.setTestWhileIdle(true);
        ds.setTestOnBorrow(false);
        ds.setTestOnReturn(false);
        ds.setTimeBetweenEvictionRunsMillis(180000);
        ds.setMinEvictableIdleTimeMillis(3600000);
        ds.setNumTestsPerEvictionRun(10);

        ds.setRemoveAbandoned(true);
        ds.setRemoveAbandonedTimeout(300);
        return ds;
    }

Spring配置示例:

<bean id="petaDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://${petadata.db.ipport}/xxx" />
    <property name="username" value="xxx" />
    <property name="password" value="xxx" />
    <!-- 配置初始化大小、最小、最大 -->
    <property name="initialSize" value="1" />
    <property name="minIdle" value="1" />
    <property name="maxActive" value="5" />
    <!-- 配置获取连接等待超时的时间 -->
    <property name="maxWait" value="3000" />
    <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
    <property name="timeBetweenEvictionRunsMillis" value="180000" />
    <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
    <property name="minEvictableIdleTimeMillis" value="3600000" />
    <property name="validationQuery" value="SELECT 1" />
    <property name="testWhileIdle" value="true" />
    <property name="testOnBorrow" value="false" />
    <property name="testOnReturn" value="false" />
    <!-- 关闭PSCache,并且指定每个连接上PSCache的大小 -->
    <property name="poolPreparedStatements" value="false" />
    <property name="numTestsPerEvictionRun" value="5" />
    <property name="removeAbandoned" value="true" />
    <property name="removeAbandonedTimeout" value="300" />
  </bean>

最佳实践

  • 首先确认您是否采用连接池访问Hybdrid DB for MySQL?如不是采用连接池访问,请改为连接池方式(dbcp、druid、c3p0等)。
  • 你的应用是否是多线程访问Hybdrid DB for MySQL,线程之间是否共享使用Connection对象?如有,请修改,最好不要在多线程间共享使用Connection对象,实现方法请参考下面sample示例代码。
  • 最好加入重试机制,保证查询访问的可用性,实现方法请参考下面sample示例代码。
static int MAX_RETRY_TIME = 3;

Connection conn = null;
Statement stmt = null;
ResultSet rs = null;

boolean executeSuccess = false;
int retryTime = 0;

while (!executeSuccess && retryTime < MAX_RETRY_TIME) {
    try {
        if (conn == null || conn.isClosed()) {
            // Get connection from data source.
            conn= dataSource.getConnection();
        }
        stmt = conn.createStatement();  
        rs = stmt.executeQuery(sql);

        // your logic ...

        executeSuccess = true;
    } catch () {
        log...
        retryTime++;

    } finally {
        try {
            if (rs != null) {
                rs.close();
            }
            if (stmt != null) {
                stmt.close();
            }
            if (conn != null) {
                conn.close();
            }
        } catch (Throwable t) {
            logging...
        }
    }
}

if (!executeSuccess) {
    log failure ….
)