关闭 Pool 中的 JDBC 连接

我们使用 JDBC 的标准代码部分是..。

Connection conn = getConnection(...);
Statement  stmt = conn.conn.createStatement (ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet  rset = stmt.executeQuery (sqlQuery);


// do stuff with rset


rset.close(); stmt.close(); conn.close();

问题1: 当使用连接池时,应该在最后关闭连接吗?如果是这样,那么共享的目的不是已经失去了吗?如果没有,DataSource 如何知道何时释放 Connection 的特定实例并可以重用?我对这个有点困惑,有什么建议吗。

问题2: 下面的方法是否接近标准?看起来像是试图从池中获取连接,如果无法建立 DataSource,则使用老式的 DriverManager。我们甚至不能确定哪个部分在运行时执行。 重复上面的问题,应该关闭从这种方法出来的连接吗?

synchronized public Connection getConnection (boolean pooledConnection)
throws SQLException {
if (pooledConnection) {
if (ds == null) {
try {
Context envCtx = (Context)
new InitialContext().lookup("java:comp/env");
ds = (DataSource) envCtx.lookup("jdbc/NamedInTomcat");
return ds.getConnection();
} catch (NamingException e) {
e.printStackTrace();
}}
return (ds == null) ? getConnection (false) : ds.getConnection();
}
return DriverManager.getConnection(
"jdbc:mysql://"+ipaddy+":"+dbPort +"/" + dbName, uName, pWord);
}

编辑: 我认为我们得到了池连接,因为我们没有看到堆栈跟踪。

102893 次浏览

当使用连接池时,应该在最后关闭连接吗?如果是这样,那么共享的目的不是已经失去了吗?如果没有,DataSource 如何知道何时释放 Connection 的特定实例并可以重用?我对这个有点困惑,有什么建议吗。

是的,当然您也需要关闭池连接。它实际上是实际连接的包装器。它将在封面下释放到池的实际连接。实际连接是关闭还是重用于新的 getConnection()调用取决于池。因此,无论您是否使用连接池,您都应该按照获得它们的 try块的 finally块的相反顺序关闭所有 JDBC 资源。在 Java7中,可以通过使用 try-with-resources语句进一步简化这一过程。


下面的方法是否接近标准?看起来像是试图从池中获取连接,如果无法建立 DataSource,则使用老式的 DriverManager。我们甚至不能确定哪个部分在运行时执行。重复上面的问题,应该关闭从这种方法出来的连接吗?

这个例子很吓人。您只需在应用程序启动期间在某个构造函数中查找/初始化 DataSource一次,即可初始化应用程序范围的 DB 配置类。然后在应用程序的剩余生命周期中对同一个数据源调用 getConnection()。不需要同步,也不需要空检查。

参见:

这些池通常返回一个已包装的 Connection 对象,其中 close ()方法被重写,通常将 Connection 返回到池。调用 close ()是可以的,可能仍然需要。

A close() method would probably look like this:

public void close() throws SQLException {
pool.returnConnection(this);
}

对于第二个问题,您可以添加一个日志记录器来显示底部块是否运行过。我可以想象,虽然对于数据库连接的配置,您只需要一种方法或另一种方法。我们只使用一个池来访问数据库。无论哪种方式,关闭连接对于防止泄漏都是非常重要的。

实际上,连接管理的最佳方法是不将它们外包给任何地方的任何代码。

创建一个 SQLExecator 类,该类是打开和关闭连接的唯一位置。

然后,应用程序的整个其余部分将语句输入到执行程序中,而不是从池中获取连接,并在各处管理(或管理不当)这些连接。

您可以拥有任意数量的执行器实例,但是任何人都不应该编写以自己的名义打开和关闭连接的代码。

方便的是,这还允许您从一组代码记录所有 SQL。