我们使用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。我们甚至不确定哪个部分在运行时被执行。 重复上面的问题,是否应该关闭连接出来的这种方法?
谢谢, - MS。
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);
}
编辑:我认为我们正在进行池化连接,因为我们没有看到堆栈跟踪。
答案 0 :(得分:109)
使用连接池时,是否应该在结束时关闭连接?如果是这样,汇集失败的目的不是?如果没有,DataSource如何知道什么时候释放Connection的特定实例并且可以重用?我对这一点感到有点困惑,任何指针都赞赏。
是的,当然你也需要关闭池化连接。它实际上是实际连接的包装器。它将在封面下释放回到池的实际连接。进一步由池决定实际连接实际是否将被关闭或重新用于新的getConnection()
调用。因此,无论您是否使用连接池,都应该始终以finally
块的try
块中的相反顺序关闭所有JDBC资源。你已经获得了它们。在Java 7中,可以使用try-with-resources
语句进一步简化。
以下方法是否接近标准?看起来是尝试从池中获取连接,如果无法建立DataSource,请使用旧式DriverManager。我们甚至不确定哪个部分在运行时被执行。重复上面的问题,是否应该使用这种方法关闭Connection?
这个例子非常可怕。您只需要在应用程序启动期间在应用程序范围的DB配置类的某些构造函数/初始化中查找/初始化DataSource
。然后在应用程序的整个生命周期中,在同一个数据源上调用getConnection()
。无需同步或无需检查。
答案 1 :(得分:21)
池通常会返回一个包装的Connection对象,其中覆盖了close()方法,通常会将Connection返回到池中。调用close()是可以的,可能仍然需要。
close()方法可能如下所示:
public void close() throws SQLException {
pool.returnConnection(this);
}
对于第二个问题,您可以添加一个记录器来显示底部块是否运行。我想,虽然你只想要一种方式来配置数据库连接。我们只使用池来进行数据库访问。无论哪种方式,关闭连接对于防止泄漏都非常重要。
答案 2 :(得分:0)
实际上,连接管理的最佳方法是不要将它们植入任何地方的任何代码中。
创建一个SQLExecutor类,该类是打开和关闭连接的唯一位置。
然后,应用程序的其余部分将语句泵送到执行器中,而不是从池中获取连接并在各处进行管理(或管理不当)。
您可以根据需要拥有任意数量的执行器实例,但是没有人可以编写自己代表打开和关闭连接的代码。
方便地,这还使您可以从一组代码中记录所有SQL。