java调用mysql c3p0函数

标签 java mysql c3p0

我有一个 java 库来查询 mysql 数据库,将 ResultSet 返回给另一个 Java 函数。由于mysql超时问题,我使用c3p0 pool来实现查询。

cpds = new ComboPooledDataSource();
cpds.setDriverClass("com.mysql.jdbc.Driver");
cpds.setJdbcUrl(url);
cpds.setUser(user);
cpds.setPassword(passwd);
cpds.setMaxPoolSize(maxPoolSize);
cpds.setMinPoolSize(minPoolSize);
cpds.setAcquireIncrement(20);


public ResultSet fetch() {
    PreparedStatement pst = null;
    ResultSet rs = null;
    String query = null;
    Connection conn = null;

    try {

        conn = cpds.getConnection();

        query = "...";
        pst = conn.prepareStatement(query);
        rs = pst.executeQuery();

    } catch (SQLException ex)  {
        Logger lgr = Logger.getLogger(Query.class.getName());                       
        lgr.log(Level.SEVERE, ex.getMessage(), ex);
    }finally {
        try {
            if(conn != null) {
                conn.close();
            }
        } catch (SQLException ex) {
            Logger lgr = Logger.getLogger(Query.class.getName());
            lgr.log(Level.SEVERE, ex.getMessage(), ex);
        }   
    }   

    return rs;
  }       
}

我遇到了这个错误

 SEVERE: Operation not allowed after ResultSet closed java.sql.SQLException: Operation not allowed after ResultSet closed 
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1075)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:989)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:984)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:929)
    at com.mysql.jdbc.ResultSetImpl.checkClosed(ResultSetImpl.java:795)
    at com.mysql.jdbc.ResultSetImpl.next(ResultSetImpl.java:7146)
    at com.mchange.v2.c3p0.impl.NewProxyResultSet.next(NewProxyResultSet.java:622)

原因很明显,但我在想调用 Mysql 查询并在函数中获取结果的最佳方式是什么。

最佳答案

在 finally 子句中,连接在方法返回之前关闭。

}finally {
    try {
        if(conn != null) {
            conn.close();
        }
    } catch (SQLException ex) {
        Logger lgr = Logger.getLogger(Query.class.getName());
        lgr.log(Level.SEVERE, ex.getMessage(), ex);
    }   
}   

此连接是由 c3p0 管理的 PooledConnection。 close() 方法只是将 Connection 返回到池中,而不关闭它。在将连接返回到池之前清理语句,以防止资源泄漏和池损坏。

当 Statements 关闭时,它的当前 ResultSet 对象(如果存在)也将关闭。检查 java 7 API 语句 close() 方法 here

因此,当 fetch() 返回时,ResultSet 被关闭。

建议:

这是 java JDBC 编程中的一个常见问题。

第一个选项,将 fetch() 更改为模板方法的代码

public ResultSet fetch(ResultSetIterator rsIterator ) {
    PreparedStatement pst = null;
    ResultSet rs = null;
    String query = null;
    Connection conn = null;

    try {

        conn = cpds.getConnection();

        query = "select * from tb_user";
        pst = conn.prepareStatement(query);
        rs = pst.executeQuery();
        
        rsIterator.iterate(rs);
        
    } catch (SQLException ex)  {
        Logger lgr = Logger.getLogger(Query.class.getName());                       
        lgr.log(Level.SEVERE, ex.getMessage(), ex);
    }finally {
        try {
            if(conn != null) {
                conn.close();
            }
        } catch (SQLException ex) {
            Logger lgr = Logger.getLogger(Query.class.getName());
            lgr.log(Level.SEVERE, ex.getMessage(), ex);
        }   
    }   

    return rs;
} 

ResultSetIterator 有处理 ResultSet 的代码

第二个选项,使用已经实现的工具,比如Commons DbUtils , 点击链接查看示例

其他选项,使用 ER 映射工具、JPA、hibernate 等...抽象连接句柄

最后,为了解决超时问题和测试连接池,使用DBCP代替 c3p0,一个更健壮的解决方案

private static DataSource setupDataSource() {
    BasicDataSource ds = new BasicDataSource();
    ds.setDriverClassName(getDriver());
    ds.setUsername(getUser());
    ds.setPassword(getPassword());
    ds.setUrl(getConnectionString());
    
    ds.setDefaultAutoCommit(false);
    ds.setInitialSize(4);
    ds.setMaxActive(60);
    ds.setMaxIdle(10);
    
    ds.setValidationQuery("/* ping */ SELECT 1");//config to validate against mysql
    ds.setValidationQueryTimeout(3);
    ds.setTestOnBorrow(true);
    ds.setTestOnReturn(true);
    
    return ds;
}

关于java调用mysql c3p0函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11306068/

相关文章:

java - Android - 如何生成 GreenDao 实体

python - IntegrityError : (1048, "Column ' username' cannot be null") when emailid is also unique key

java - 如何在我的 GWT 小工具中使用本地 MySQL 服务器?

java - 警告 c3p0 : Another error has occurred: Connection is Closed

java - 如何为具有多个数据源的 grails 2.X 应用程序配置 c3p0?

java - JAVA中多线程的全局求和错误

java - 在 Apache Spark 中提交应用程序

java - 多线程 OpenGL-List 创建

php - 计算 while 循环的每个实例的记录

java - OSGi 上的 PostgreSQL 连接器