Java中JDBC资源必须按ResultSet→Statement→Connection顺序显式关闭,因存在依赖关系;推荐使用try-with-resources自动管理,资源需在try()内声明初始化,关闭按逆序执行,异常时主异常优先、关闭异常被抑制。

Java 中 JDBC 资源必须显式关闭,否则容易导致连接泄漏、内存占用上升甚至数据库连接池耗尽。核心原则就一条:谁创建、谁负责关;按依赖逆序关;异常不中断关闭流程。
必须按 ResultSet → Statement → Connection 顺序关闭
这是由资源依赖关系决定的——ResultSet 内部持有 Statement 引用,Statement 又依赖 Connection。如果先 close Connection,再调用 ResultSet.next() 或 Statement.execute(),大概率抛出 “Connection closed” 或 “Statement closed” 异常,且后续关闭动作可能被跳过。
- ✅ 正确顺序:ResultSet.close() → Statement.close() → Connection.close()
- ❌ 错误示例:Connection 先关,ResultSet 后读取 → 直接报错,且 ResultSet 和 Statement 可能没真正释放
推荐用 try-with-resources(JDK 7+)
只要 JDBC 驱动版本 ≥ JDBC 4.0(对应 ojdbc6+,实际建议 ojdbc8 或更高),Connection、Statement、ResultSet 都实现了 AutoCloseable 接口,可直接用 try-with-resources 自动管理。
- 资源必须在 try( ) 括号内声明并初始化,例如:
try (Connection c = ds.getConnection(); PreparedStatement ps = c.prepareStatement(sql); ResultSet rs = ps.executeQuery()) { ... } - 关闭顺序是声明的逆序:rs 最先关,ps 次之,c 最后关,天然符合依赖逻辑
- 即使 try 块中抛异常,close() 仍会执行;若 close 过程也抛异常,会被抑制(suppressed),主异常仍向上抛出,可通过
e.getSuppressed()查看
传统 finally 方式要严守三要素
兼容旧环境或需精细控制时,用 try-catch-finally 也可靠,但必须满足三个条件:
立即学习“Java免费学习笔记(深入)”;
- 变量提前声明为 null:Connection conn = null; PreparedStatement ps = null; ResultSet rs = null;
- 每个 close() 独立判空 + 独立 try-catch:避免一个 close 失败导致后续资源无法释放
- finally 中不 return、不 throw:否则可能吞掉 try 或 catch 中的关键异常
别依赖 Connection.close() 自动级联关闭
虽然部分驱动文档说 Connection.close() 会自动关闭其创建的所有 Statement 和 ResultSet,但这不是 JDBC 规范强制要求,且行为因驱动而异。Oracle、MySQL 等主流驱动虽通常支持,但:
- 连接池场景下,
Connection.close()实际是归还连接,未必触发 Statement/ResultSet 物理关闭 - ResultSet 未显式关闭,可能导致游标未释放、数据库端资源持续占用
- 明确关闭所有资源是最稳妥、可移植性最强的做法


















