当前位置: 首页 > 知识库问答 >
问题:

C3p0准备好的声明无故关闭

祖奇
2023-03-14

我用的是c3p0。我建立了一个池,如下所示,

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

我有一个对象,准备初始化的几个准备好的语句。为了做到这一点,我从PooledDataSource中抓取一个连接(con=getConnection()),然后准备一个语句(例如,准备声明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语句缓存的用途是什么。

共有1个答案

公良修竹
2023-03-14

调用executeUpdate()时应该会出现相同的异常。JDBC连接和语句池的设计是透明的:用于非OLED数据源的相同API也应用于池版本。性能上会有巨大的差异,但是代码应该在语义上是可互换的。

在非OLED环境中,您的方法失败的原因应该是显而易见的:一条语句,不管是准备好的还是其他的,都是连接的子项,没有它就无法运行。您希望在池环境中,即使连接已“关闭”,它仍应存在于池中,因此,这些语句可能是好的。但这是一个非常糟糕的想法(如果在父连接关闭()后,您尝试进行更新的尝试真的成功了,那么这将是一个错误,一个糟糕的错误)一旦一个连接被“关闭”,它就会回到池中,但不是永远。其他客户机将检查它,并开始执行不应该被您的陈旧语句打断的事务工作。最终连接将从池中过期。那么,你保留的准备好的报表怎么办?

c3p0透明地池语句,这意味着您应该使用与不使用池时完全相同的API。调用prepareStatement(…)在你的连接上,每次。如果您已经在c3p0中启用了语句池(正如您所做的那样),那么c3p0将在内部检查语句是否已经准备好,如果已经准备好,它将悄悄地使用缓存版本,而不是将请求转发到dbms。

我希望这能有所帮助!

 类似资料:
  • 问题内容: 何时使用语句而不是准备语句。我想在没有参数的查询中使用语句,但是为什么不使用预处理语句呢?对于没有参数的查询,哪一个更快。 问题答案: 我想在没有参数的查询中使用语句,但是为什么不使用预处理语句呢? 还差得远 对于返回结果集或更新计数的INSERT,UPDATE和DELETE语句,使用PreparedStatement。正如Joachim所指出的,它们不适用于DDL语句,也不适用于应使

  • 我正在使用PreparedStatement的setString方法来设置sql查询中开始日期和结束日期的值。 但是这些值没有被设置。我知道通常有一个等号:“tableA.member_id = ?" " 当我在sql语句中使用“Between”运算符时,如何调用setString方法?希望有人能提出建议。非常感谢。

  • 我们可以在使用Java的PreparedStatement中使用OR子句吗?

  • 我有一个网站,点击量很大。我遇到过一些问题,包括JDBC连接错误。 我对结束PreparedStatement有点困惑。我需要关闭PreparedStatement吗?还是只需要关闭语句就足够了? 另外,呢?我也需要关闭它吗?

  • 我(试图)将我的查询从未准备好的语句移到MySQLi准备好的语句。到目前为止,我所学到的应该在下面的模式中发生: 编辑:如果我在准备语句后print_r,我将得到: 如果我在bind_param后面print_r得到的语句: 如果我在执行语句后print_r,我会得到: 但是我如何循环计算结果呢? 这似乎不起作用:-/

  • 我并不完全理解预准备语句的概念,但是根据python驱动程序文档,预准备语句是< code >“针对至少一个Cassandra节点准备的语句”。对我来说,在集群中的某个地方有关于已经准备好的查询的信息。该文档还规定< code >“prepared statement应该只准备一次。重新准备语句可能会影响性能(因为该操作需要网络往返),"。 如果我的概念是正确的,那么从集群中接收已经准备好的语句而