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

时间:2009-10-26 15:24:59

标签: java jdbc connection-pooling

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

该错误看起来基本上是剪切和粘贴错误。我们有一些管理数据库连接的类,所以看起来大致如下:

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
}

我不知道为什么早期的程序员不只是重用原始连接,但这就是它的原因

(开始编辑/追加)

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

但是,我不认为我问了正确的问题,尽管下面的答案回答了我提出的问题。我不确定正确的stackoverflow要做的是什么;问另一个问题,还是编辑一个?

我应该问的一个问题是:这些孤立的,未封闭的连接如何在系统性能中表现出来?此外,由于这些连接对象仅存在于某个方法的范围内,因此连接是否有资格进行垃圾回收?然后,如果他们是gc'ed,开放连接是gc'ed的影响是什么?

(结束编辑)

2 个答案:

答案 0 :(得分:7)

假设连接管理器也是您自己的代码,您可以将初始化的连接(以及堆栈跟踪)存储在连接管理器中的映射中,然后在返回它们时将其删除。因此,在任何时候,映射的键集都是未返回的连接集,您可以在映射中查找该值,以便找到创建它们并且从不释放它们的有罪代码。 (如果连接不是合适的地图密钥,您可以使用某种唯一的ID或连接号或其他 - 实际值与其存在无关紧要。)

然后只需添加一些适当的方式来按需访问此地图,你就会很好。根据您的环境,添加将地图内容转储到文件的关闭挂钩,和/或添加JConsole接口以查找正在运行的代码中的未关闭连接集,这两者都是不错的选择。

如果连接管理器不是您的代码,您仍然可以使用方面实现相同的功能。

答案 1 :(得分:0)

您可以实现自定义迷你框架或使用exisitng作为JDBC操作的瘦包装器。例如,有一个spring-jdbc模块(mavenized),它涵盖了开发人员的所有样板错误代码。

你可以查看它的usage examples,看看客户端代码根本没有初始化/清理!它使用'模板方法'模式,即您只需编写基本数据处理,而不必担心连接/语句/结果集的创建和关闭。因此,首先无法介绍您所谈论的问题。