[英]Java Connection Pooling - garbage collection or call close()?
我担心的是,在理解Java中的连接池方面存在一个基本问题。
我正在使用IDBCDataSource作为连接池。 在我的应用程序的入口点,我实例化了一个BasicDataSource,例如setMaxActive = 50。 然后,将该数据源的实例移交给某些业务逻辑使用的各种DAO。
每个DAO都调用getConnection(),但没有调用单个close()。 我的假设是,在不使用DAO之后,垃圾收集器将关闭连接。
我的问题是Im经常用尽连接(即代码等待可用连接)。
现在说我将在每个数据库操作的末尾添加一个close()调用。 抛出异常会发生什么。 我必须捕获DAO中的每个Exception,确保关闭连接,然后重新引发发生的Exception!
示例 -当前方法:
public class MyDAO {
private Connection con;
public MyDAO (DataSource ds) {
con = ds.getConnection();
}
public MyReturnClass execSomeQuery() throws SQLException {
String sql = String.format("SELECT * FROM foo");
PreparedStatement ps = con.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
…
...
}
return result;
}
}
public class MyAppLogic() {
DataSource ds;
public MyAppLogic(DataSource ds) {
this.ds = ds;
}
public void doSomeStuff() {
MyDAO myDAO = MyDAO(ds);
myDAO.execSomeQuery();
}
}
您需要close
连接,以便它们返回连接池中。 GC不会关闭您的连接!
您可以创建用于管理连接的包装器或父类,这样就不必在每个方法中都复制逻辑。 这是一个示例(请注意,我尚未对此进行实际编译或测试)。
public interface DAOClass {
public void execSomeQuery() throws SQLException;
}
public class MyDAOWrapper {
private DAOClass dao;
private DataSource ds;
public MyDAOWrapper(DataSource ds, DAOClass dao) {
this.dao = dao;
this.ds = ds;
}
public void exec() throws SQLException {
Connection con = ds.getConnection();
try {
dao.execSomeQuery();
}
finally {
con.close();
}
}
}
// usage
public void doSomeStuff() throws SQLException {
MyDAOWrapper dao = new MyDAOWrapper(ds, new MyDAO());
dao.exec();
}
关于错误处理,除非捕获到异常,否则无需重新抛出异常。 您的finally
子句应关闭连接(如果存在),并且当连接退出时,异常将继续传播。
try {
do_something();
}
finally {
cleanup();
// throw is not necessary
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.