是否可以在不同的连接上执行 CallableStament?

Posted

技术标签:

【中文标题】是否可以在不同的连接上执行 CallableStament?【英文标题】:Is it possible to execute a CallableStament on a different Connection? 【发布时间】:2013-10-07 00:22:16 【问题描述】:

通常认为重用CallableStatement 的实例是一种好习惯(检查here)。

但是在创建CallableStatement 时,该语句(据我的理解)是有约束力的 到特定的Connection。所以我们通常会这样做:

Connection con = pool.getConnection();
CallableStatement st = con.prepareCall(" some stmt; ");
st.executeQuery();
st.close();
con.close();            

根据我的检查,以下内容不会执行查询:

Connection con = pool.getConnection();
CallableStatement st = con.prepareCall(" some stmt; ");
con.close();
con = pool.getConnection(); // possibly another new connection, different than the one used to create the CallableStatement instance
st.executeQuery();
st.close();

我的问题是:如果我想重用所有CallableStatement 实例,但另一方面仍然能够获得新连接并关闭旧连接(并非总是打开相同的连接) 我能做什么?

【问题讨论】:

【参考方案1】:

PreparedStatements 已(或应该)由您的 JDBC 驱动程序缓存。参见例如http://www.mchange.com/projects/c3p0/

这意味着您不应保留一个并在连接之间使用,但不用担心,您的驱动程序会为您管理缓存。本质上,每个连接都会缓存自己的缓存,因此如果您有 5 个连接,那么您将有 5 个缓存副本,这可能足够小。

调用prepareStatement 将从缓存中检索,如果没有缓存,则分配。所以重复调用prepareStatement 是轻量级的。这才是 API 的正确用法。

参见例如Oracle's docs 在技术上是特定于 Oracle 的,但我相信这些信息是标准的。

【讨论】:

所以,这意味着每次在执行查询之前都可以执行prepareCall 吗?我没有完全理解你的回答。它们被缓存了,所以我可以多次调用相同的prepareCall 吗? @foobar IIRC,是的,这是正确的。每次调用prepareCall,JDBC 会检查它是否已经在缓存中。 谢谢您,这回答了我的问题(将在 5 分钟内接受您的回答)。如果您可以将您的评论答案附在您的真实答案中,那就太好了。谢谢;)

以上是关于是否可以在不同的连接上执行 CallableStament?的主要内容,如果未能解决你的问题,请参考以下文章

Tomcat 连接池问题 - 无法在关闭的连接上调用方法

如何修改正在进行的连接上的流以暂停/恢复流传输

TomEE 中的 Spring Durable JMS 订阅者(不允许在使用的连接上设置 clientID)

冲刺阶段 day 9

MultipleActiveResultSets=True 还是多个连接?

PDO 参数化与非参数化查询速度