是否可以在不同的连接上执行 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】:PreparedStatement
s 已(或应该)由您的 JDBC 驱动程序缓存。参见例如http://www.mchange.com/projects/c3p0/
这意味着您不应保留一个并在连接之间使用,但不用担心,您的驱动程序会为您管理缓存。本质上,每个连接都会缓存自己的缓存,因此如果您有 5 个连接,那么您将有 5 个缓存副本,这可能足够小。
调用prepareStatement
将从缓存中检索,如果没有缓存,则分配。所以重复调用prepareStatement
是轻量级的。这才是 API 的正确用法。
参见例如Oracle's docs 在技术上是特定于 Oracle 的,但我相信这些信息是标准的。
【讨论】:
所以,这意味着每次在执行查询之前都可以执行prepareCall
吗?我没有完全理解你的回答。它们被缓存了,所以我可以多次调用相同的prepareCall
吗?
@foobar IIRC,是的,这是正确的。每次调用prepareCall
,JDBC 会检查它是否已经在缓存中。
谢谢您,这回答了我的问题(将在 5 分钟内接受您的回答)。如果您可以将您的评论答案附在您的真实答案中,那就太好了。谢谢;)以上是关于是否可以在不同的连接上执行 CallableStament?的主要内容,如果未能解决你的问题,请参考以下文章
TomEE 中的 Spring Durable JMS 订阅者(不允许在使用的连接上设置 clientID)