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

标签 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 的效果是什么?

(结束编辑)

最佳答案

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

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

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

关于java - 如何跟踪未关闭的孤立 JDBC 连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1625465/

相关文章:

java - 如何将新实例添加到通用列表?

java - 线路输入节拍检测

mysql - JDBC连接不同Host上的MySQL所使用的协议(protocol)

java - 准备语句错误

java - PoolingHttpClientConnectionManager 如何管理连接?

sql - Golang 上全局数据库连接和每次打开连接的性能差异

java - 使用 jOOQ 和 PostgreSQL serial 和 RETURNING 返回一个值

java - 如何在插件 REST Spring Atlassian Connect API 中实现 JWT 授权?

django - pgbouncer 与 Django 的 CONN_MAX_AGE 的理想设置

java - 如何在 Java 中构建查询以防止使用准备好的语句进行 SQL 注入(inject)