开发者社区> 问答> 正文

Operation not allowed after ResultSet closed

我在用jdbc对数据库进行dump,可以理解就是 select * from table1 limit 100 where id > xxx,不断的从数据库批量取数据

连接池管理用的druid(这也许是个错),然后不知道为什么,在线上跑一段时间就会报

java.sql.SQLException: Operation not allowed after ResultSet closed at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1084) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:987) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:973) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:918) at com.mysql.jdbc.ResultSetImpl.checkClosed(ResultSetImpl.java:799) at com.mysql.jdbc.ResultSetImpl.checkRowPos(ResultSetImpl.java:847) at com.mysql.jdbc.ResultSetImpl.getObject(ResultSetImpl.java:4877) at com.alibaba.druid.pool.DruidPooledResultSet.getObject(DruidPooledResultSet.java:439)

刚开始怀疑是mysql JDBC driver的问题 查了很多资料,最后发现一个人跟我情况类似,下面有个回答说,你是不是用了dbcp? 我后来想想,我也是用了druid来做连接池.

然后我后来弃用了druid,错误果然就没有报了.

所以我怀疑,druid是不是在我不期望的情况下关闭了我的数据库连接?

以下是我的druid配置

DruidDataSource dataSource = new DruidDataSource();

dataSource.setUrl(url);

// 设置属性
dataSource.setMaxActive(2);
dataSource.setInitialSize(1);
dataSource.setMaxWait(5000);
dataSource.setMinEvictableIdleTimeMillis(30000);
dataSource.setMaxEvictableIdleTimeMillis(300000);
dataSource.setPoolPreparedStatements(true);
dataSource.setTestWhileIdle(true);
dataSource.setTestOnBorrow(false);
dataSource.setTestOnReturn(false);
dataSource.setPhyTimeoutMillis(1800000);
dataSource.setRemoveAbandoned(true);
dataSource.setRemoveAbandonedTimeout(180);
dataSource.setValidationQuery("select 1");
dataSource.setValidationQueryTimeout(1);
dataSource.setTimeBetweenEvictionRunsMillis(10000);
dataSource.setDefaultAutoCommit(true);
dataSource.setConnectionProperties("connectTimeout=1000;socketTimeout=3000");

原提问者GitHub用户yuankui

展开
收起
山海行 2023-07-05 21:06:58 205 0
3 条回答
写回答
取消 提交回答
  • 根据您提供的信息,当使用Druid连接池进行数据库dump操作时,出现了"Operation not allowed after ResultSet closed"异常。这通常是由于已经关闭的ResultSet对象再次被使用导致的。

    在您的情况下,可能是由于Druid连接池的某些配置问题导致的。具体来说,可能是由于设置了dataSource.setRemoveAbandoned(true)dataSource.setRemoveAbandonedTimeout(180)属性,而导致连接被过早地关闭,进而导致ResultSet对象在尚未完全使用完毕时被关闭。

    为了解决这个问题,您可以尝试以下方法:

    1. 检查连接池的其他配置项。确保连接池的相关配置(如最大活动连接数、最小空闲连接数等)合理设置,并与实际需求匹配。

    2. 调整setRemoveAbandonedsetRemoveAbandonedTimeout属性的设置。如果您确实需要设置这两个属性,可以适当调整setRemoveAbandonedTimeout的值,以延长连接被认定为"废弃"并被关闭的时间。例如,将其设置为更大的值,如300或更长的时间。

    3. 检查代码中是否正确地关闭ResultSet和相关资源。确保在使用ResultSet对象之后,及时地调用ResultSet.close()方法释放资源。

    4. 如果以上方法都没有解决问题,建议查阅Druid的文档和社区资源,寻找类似问题和解决方案的建议

    2023-07-30 14:37:24
    赞同 展开评论 打赏
  • 北京阿里云ACE会长

    如果您在使用JDBC对数据库进行dump时,出现了java.sql.SQLException: Operation not allowed after ResultSet closed异常,这通常是由于已经关闭的ResultSet对象被再次使用导致的。

    在您的情况下,可能是由于连接池中的某些连接在使用过程中出现了问题,从而导致ResultSet对象在没有完全使用完毕的情况下被关闭。当您尝试再次使用已经关闭的ResultSet对象时,就会出现Operation not allowed after ResultSet closed异常。

    2023-07-30 13:06:17
    赞同 展开评论 打赏
  • dataSource.setRemoveAbandoned(true); dataSource.setRemoveAbandonedTimeout(180); 问题出在这两个属性的设置

    原回答者GitHub用户zhouguanglong1

    2023-07-06 11:54:09
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载