何时关闭 JDBC 中的 Connection、Statement、PreparedStatement 和 ResultSet

Posted

技术标签:

【中文标题】何时关闭 JDBC 中的 Connection、Statement、PreparedStatement 和 ResultSet【英文标题】:When to close Connection, Statement, PreparedStatement and ResultSet in JDBC 【发布时间】:2010-11-05 13:57:25 【问题描述】:

关于 JDBC 编码的几个问题:

    对于单个客户端应用程序,我们是否需要连接池? 在开始时创建一个Connection 并保持它处于活动状态而不关闭它直到应用程序退出是个好主意吗?为什么? PreparedStatementConnection 关联,如果每次查询后我的连接都没有关闭,为什么不保持 PreparedStatement 处于活动状态并在其他方法中重用它? 如果我们为每个查询创建PreparedStatement,数据库是否知道它是相同的PreparedStatement,并在第一次之后忽略不必要的操作? PreparedStatement 不是创建一次重用多次语句吗?如果是,为什么每次都需要关闭?

我知道调用close() 将释放资源。但是如果我们知道以后会用到它,为什么要发布它,然后再请求它呢?

多客户端应用程序怎么样?我们需要一个连接池,所以每次都需要创建和关闭Connection、StatementPreparedStatement

【问题讨论】:

***.com/questions/4507440/… 【参考方案1】:

我个人会使用池,因为它会为您处理所有资源管理。如果您的连接要求发生变化,那么您可以轻松修改池配置。使用适当的池,您可以根据最佳实践打开/关闭连接和准备好的语句,并将资源管理留给池。

通常,在使用池时:

关闭连接实际上只会将其返回到池中 准备语句的行为将从 Connection 的语句缓存中检索先前准备的语句,或者如果没有可用的语句,则创建一个新语句并将其缓存以供以后使用。 关闭 PreparedStatement 的行为实际上只是将其返回到连接的语句缓存中。

此外 - 取决于池的实现 - 它可能会在发生资源泄漏时通知您,从而更容易识别代码中的此类问题。

看看像 DBCP 这样的示例实现的源代码 - 看看它们是如何工作的非常有趣。

【讨论】:

不要相信你的池:***.com/questions/4507440/… @teabot 我在每次查询执行后关闭所有对象,包括 Connection 。为每个请求而不是每个语句打开和关闭连接是否更好?我的意思是,语句和结果集每次使用都关闭,但每个请求的连接都是一个(在请求开始时打开并在最后一个结束时关闭查询执行) @teabot 你能更新最佳实践链接吗,它是 404【参考方案2】:

1. 即使您只有一个客户端,连接池也可能是有益的。连接到数据库可能需要很长时间,因此经常这样做可能会因网络请求缓慢而降低应用程序的速度。此外,正如@teabot 解释的那样,池可能有助于识别是否有任何连接没有关闭。

2. 出于两个原因,打开连接并使其永远打开并不是一个好主意。首先,如果网络暂时中断,连接可能会中断。它打开的时间越长,它就越有可能在需要时死掉。其次,失败的事务可能会使连接处于不适合继续操作的状态。最好的办法通常是打开几个连接,重复使用五到十分钟,然后循环使用。

3. 根据数据库和驱动程序,连接可能有准备好的语句缓存。即使使用不同的连接,RDBMS 通常也会缓存完全相同的语句,包括它的参数。因此 SELECT * FROM table WHERE value=?因为准备好的语句将跨连接缓存,但如果您指定参数值 SELECT * FROM table WHERE value='your_data' 那么它可能不会被缓存在服务器端。

4. 如 3 所述,取决于 RDBMS 的实现,做一个基准测试。

5. 没有必要关闭并再次准备一个语句,该语句将被不同的参数重用。只需重新设置参数并执行即可。

对于多个客户端,数据库总是有一个并发连接限制,通常不是很大的数字。如果所有客户端都通过 webapp,那么像 DBCP 这样的池就可以了。但显然不希望为每个客户端创建一个永久打开多个连接的池。

【讨论】:

以上是关于何时关闭 JDBC 中的 Connection、Statement、PreparedStatement 和 ResultSet的主要内容,如果未能解决你的问题,请参考以下文章

Java JDBC中的Concat SQL [关闭]

在使用 JDBC 的 DAO 类中,哪一个是处理关闭 ResultSet、PreparedStatement 和 Connection 的 try-catch 的最佳方法?

数据源连接池未关闭的问题 Could not open JDBC Connection for transaction

JDBC连接池与工具类

Java数据库连接关闭后无法启动

SqlServer SQLException 该连接已关闭