impala 使用连接池报“Cannot get a connection, pool exhausted”异常

最近在使用dbcp 为impala创建连接池时,创建的时候没有报错,但是取连接的时候发现报错了,错误信息如下:

1
Caused by: org.apache.commons.dbcp.SQLNestedException: Cannot get a connection, pool exhausted

通过debug发现连接池中的连接数为0,断定是创建连接池的时候出了异常。
于是debug进入commons dbcp的源代码中,发现在PoolableConnectionFactory中的passivateObject(Object obj)方法中出了异常。

public void passivateObject(Object obj) throws Exception {
    if(obj instanceof Connection) {
        Connection conn = (Connection)obj;
        if(!conn.getAutoCommit() && !conn.isReadOnly()) {
            conn.rollback();
        }
        conn.clearWarnings();
        //由于impala没有事务,所以设置自动提交必然失败
        conn.setAutoCommit(true);
    }
    if(obj instanceof DelegatingConnection) {
        ((DelegatingConnection)obj).passivate();
    }
}

发现dbcp代码有问题后,首先看了下版本号1.2.1。进入官网后,发现有1.4的新版本,于是下载下来后,查看源代码:

public void passivateObject(Object obj) throws Exception {
    if(obj instanceof Connection) {
        Connection conn = (Connection)obj;
        if(!conn.getAutoCommit() && !conn.isReadOnly()) {
            conn.rollback();
        }
        conn.clearWarnings();
        if(!conn.getAutoCommit()) {
            conn.setAutoCommit(true);
        }
    }
    if(obj instanceof DelegatingConnection) {
        ((DelegatingConnection)obj).passivate();
    }
}

发现在1.4的代码中已经先判断连接自动提交的状态再设置。果断更新dbcp后,运行一切正常。