Java 如何跟踪未关闭的孤立JDBC连接?

Java 如何跟踪未关闭的孤立JDBC连接?,java,jdbc,connection-pooling,Java,Jdbc,Connection Pooling,我们在旧代码中发现了一个错误,连接没有关闭。这是一个简单的修复,但我想知道我们如何证明它是修复的。可以选择是否使用连接池。对于池的使用,可以很容易地为池添加监控,但是当不使用连接池时,我们如何跟踪那些未关闭的孤立连接?它和其他内存泄漏一样吗 这个bug看起来基本上是一个剪切粘贴错误。我们有几个类管理DB连接,因此大致如下所示: OurDBConn conn1 = ConnectionManager.getConnection(); try { // business logic } catc

我们在旧代码中发现了一个错误,连接没有关闭。这是一个简单的修复,但我想知道我们如何证明它是修复的。可以选择是否使用连接池。对于池的使用,可以很容易地为池添加监控,但是当不使用连接池时,我们如何跟踪那些未关闭的孤立连接?它和其他内存泄漏一样吗

这个bug看起来基本上是一个剪切粘贴错误。我们有几个类管理DB连接,因此大致如下所示:

OurDBConn conn1 = ConnectionManager.getConnection();
try {
  // business logic
} catch () {
  //
} finally {
  ConnectionManager.returnConnection(conn1);
}

/// and then later in the same method
OurDBConn conn2 = ConnectionManager.getConnection();
try {
  // business logic
} catch () {
  //
} finally {
  ConnectionManager.returnConnection(conn1); // NOTE Error: conn1 should be conn2
}
我不知道为什么早期的编码人员不只是重复使用原始连接,但事实就是这样

(开始编辑/追加)

是的,连接代码也是我们的,因此我可以使用给出的答案

然而,我认为我问的问题不对,尽管下面的答案回答了我的问题。我不确定该做什么;问另一个问题,或者编辑这个问题

我应该问的一个问题是:这些孤立的、未关闭的连接如何在系统性能中表现出来?此外,由于这些连接对象只存在于某个方法的范围内,那么这些连接不符合垃圾收集的条件吗?如果它们是gc'ed,那么gc'ed对开放连接有什么影响


(结束编辑)

假设连接管理器也是您自己的代码,您可以将初始化的连接(连同stacktrace)存储在连接管理器内的映射中,然后在返回时将其删除。因此,在任何一点上,映射的键集都是一组未返回的连接,您可以在映射中查找该值,以找到创建它们但从未释放它们的代码的错误位。(如果连接不是一个合适的映射键,您可能会使用某种唯一的ID或连接号或其他任何东西-实际值与其说是它的存在,不如说是它的存在)

然后,只要添加一些适当的方式按需访问此地图,就可以了。根据您的环境,添加将映射内容转储到文件的关闭钩子和/或添加JConsole接口以查找运行代码中未关闭的连接集都是不错的选择


如果连接管理器不是您的代码,那么您仍然可以使用aspects实现同样的功能。

您可以实现自定义迷你框架,或者使用现有框架作为JDBC操作的瘦包装。例如,有一个模块()涵盖了开发人员提供的所有易于出错的样板代码


您可以检查它,看到客户端代码中根本没有初始化/清理!它使用“模板方法”模式,也就是说,您只需编写基本的数据处理,而不必费心创建和关闭连接/语句/结果集。因此,不可能介绍您最初提到的问题。

我将密切关注这一问题,我们的几个项目中都有一个非常类似的问题。作为记录,我需要有一个很好的理由不把它移到一个成熟的连接池实现,比如DCP或C3PO——如果你有机会的话,也许你应该考虑这样做。我们使用的连接池做了非常类似的事情。我相信它会包装它返回的连接,并跟踪它们何时被使用。如果一个连接的未使用时间超过了我们在配置中指定的一定时间,那么该连接将自动终止,并将连接打开时记录的堆栈跟踪打印到日志中。