【问题标题】:still having You can't operate on a closed ResultSet error after using connection pool仍然有 You can't operation on a closed ResultSet error after using connection pool
【发布时间】:2014-10-05 01:09:38
【问题描述】:

我有很多线程访问MYSQL数据库,一开始我没有使用连接池,所以出现了这个错误“You can't operation on a closed ResultSet”

我在谷歌上搜索,发现我应该使用连接池,所以我尝试了 c3p0 API 来实现,但我仍然遇到同样的问题,没有任何改变。 所以我应该同步 getAllcountries 方法还是有另一个更好的解决方案。

public class DataSource {

private static DataSource datasource;
private ComboPooledDataSource cpds ; 

private DataSource() throws IOException, SQLException, PropertyVetoException {
    cpds = new ComboPooledDataSource();
    cpds.setDriverClass("com.mysql.jdbc.Driver"); //loads the jdbc driver
    cpds.setJdbcUrl("jdbc:mysql://localhost/question_game");
    cpds.setUser("root");
    cpds.setPassword("");
    cpds.setMaxPoolSize(500);
    }

public static DataSource getInstance() throws IOException, SQLException, PropertyVetoException {
    if (datasource == null) {
        datasource = new DataSource();
        return datasource;
    } else {
        return datasource;
    }
}

public  Connection getConnection() throws SQLException {
    return this.cpds.getConnection();
}


public  List<Country> getAllCountries() {
    String query = "SELECT * FROM country order by name ";
    List<Country> list = new ArrayList<Country>();
    Country country = null;
    ResultSet rs = null;
    try {
        try {
            connection = DataSource.getInstance().getConnection();
            } catch (IOException e) {
            e.printStackTrace();
        } catch (PropertyVetoException e) {
            e.printStackTrace();
        }
        statement = connection.createStatement();
        rs = statement.executeQuery(query);
        while (rs.next()) {
              //getting countries
        }
    } catch (SQLException ex) {
        ex.printStackTrace();
    } finally {
        //DbUtil used to check if null 
        DbUtil.close(rs);
        DbUtil.close(statement);
        DbUtil.close(connection);
    }
    return list;

}

【问题讨论】:

    标签: java mysql multithreading jdbc c3p0


    【解决方案1】:

    除了@stephen-c 的观察, 您基本上有两个选择:要么同步 getAllCountries 方法,要么将数据库连接设置为该方法的本地连接,而不是将其作为类成员。

    正如您现在所拥有的,'connection' 是一个类成员(可用于所有线程上的所有 getAllCountries() 调用),因此连接可能被第二个线程覆盖。将其移动到方法中的一个变量中,然后方法的每次调用都会有自己的连接。

    【讨论】:

      【解决方案2】:

      我看到一个名为getConnection 的方法,我看不出你在哪里调用它。相反,我看到您的 getAllCountries 方法使用静态 DataSource 对象,该对象是这样创建的:

      new DataSource();
      

      我在谷歌上搜索,发现我应该使用连接池,所以我尝试了 c3p0 API 来实现,但我仍然遇到同样的问题,没有任何改变

      是的……

      看起来您只是将找到的代码剪切并粘贴到您的应用程序中,而没有真正考虑它。显然...您需要了解代码在做什么,并弄清楚如何在您的应用程序中使用它

      【讨论】:

      • 我正在使用 getInstance() 方法,因为我只想要一个 DataSource 实例。
      • 不是数据源被关闭,而是从数据源获得的连接被替换。
      猜你喜欢
      • 2022-12-02
      • 2020-12-15
      • 2018-10-21
      • 2019-12-02
      • 1970-01-01
      • 2017-08-06
      • 1970-01-01
      • 2021-10-03
      • 2022-12-02
      相关资源
      最近更新 更多