加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – c3p0准备好的声明因没有明显原因而关闭

发布时间:2020-12-15 04:11:49 所属栏目:Java 来源:网络整理
导读:我正在使用c3p0.我建立了一个汇集如下, cpds = new ComboPooledDataSource();cpds.setJdbcUrl(...);/* connection setup */spds.setMaxStatements(200); 我有一个对象,准备几个准备好的语句初始化.为了做到这一点,我从PooledDataSource获取连接(con = getCon
我正在使用c3p0.我建立了一个汇集如下,

cpds = new ComboPooledDataSource();
cpds.setJdbcUrl(...);
/* connection setup */
spds.setMaxStatements(200);

我有一个对象,准备几个准备好的语句初始化.为了做到这一点,我从PooledDataSource获取连接(con = getConnection()),然后准备一个语句(例如,PreparedStatement stmt = con.preparedStatemet(/ * sql * /)).准备好的语句作为私有变量存储在对象中,当前连接在初始化结束时关闭(con.close()).准备好的语句用于对象的方法.

对于更新数据库的预准备语句,这很好用.但是,当我调用一个使用预准备语句(stmt.executeQuery())来查询数据库的方法时,我得到以下SQLException

java.sql.SQLException: You can't operate on a closed Statement!!!
at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:118)
at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:77)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewProxyPreparedStatement.java:127)

我对c3p0的使用有什么不妥吗?

提前谢谢了!

编辑:显然,我的问题部分是基于我缺乏理解.正如在明确答案中指出的那样,PreparedStatement属于一个连接,每当连接关闭时,关联的语句也应该被关闭.但如果是这种情况,我不明白使用c3p0的语句缓存是什么.

解决方法

你应该得到相同的异常调用executeUpdate(). JDBC连接和语句池设计为透明的:用于非池化数据源的相同API也应该用于池化版本.性能会有很大差异,但代码应该在语义上可以互换.

在一个非池化的环境中,你的方法失败的原因应该是显而易见的:一个声明,准备好或以其他方式,是一个连接的子,没有它就无法运行.你希望在集合环境中,即使Connection已经“关闭”,它仍然应该存在于池中,所以嘿,这些陈述可能是好的.但这是一个非常糟糕的主意(并且如果你在父连接已经关闭()之后你的尝试做更新真的是成功的,那么,这将是一个错误,一个坏的.)一旦连接被“关闭”它回到游泳池,但不是永远.其他客户将检查它,并开始执行不应被陈旧陈述中断的交易工作.最终,Connections将从池中过期.那么你保留的PreparedStatements会发生什么?

c3p0池语句透明,这意味着您应该使用完全相同的API,而不使用池.每次都要在Connection上调用prepareStatement(…).如果你已经在c3p0中启用了语句池(就像你一样),那么内部c3p0将检查是否已经准备好Statement,如果是,它将悄悄地使用缓存版本而不是将请求转发给dbms.

我希望这有帮助!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读