我在一些不使用连接池的旧 Java Web 应用程序中存在连接泄漏。
试图找到泄漏是很困难的,因为 IT 不会授予我访问 v$session SELECT Count(*) FROM v$session;
所以我尝试使用 System.out 语句进行调试。即使在关闭连接之后,当我将 conn 打印到系统日志文件时,它也会为我提供连接对象名称。
try {
Connection conn;
conn.close()
}
catch (SQLException e) { }
finally {
if (conn != null) {
try {
System.out.println("Closing the connection");
conn.close();
}
catch (Exception ex)
{
System.out.println("Exception is " + ex);
}
}
}
// I then check conn and it is not null and I can print the object name.
if (conn != null) {
System.out.println("Connection is still open and is " + conn);
}
但是,如果我还在 conn.close();
语句下方添加 conn = null;
,则连接现在似乎已关闭。所以我的问题是 conn.close(); 吗?实际释放我的连接还是我还必须将其设置为空才能真正释放我的连接。就像我说的,在无法查询 v$session 的情况下,我真的很难确定连接是否真的被释放。是否有 java 代码片段可以为我提供打开的连接?
此时这可能具有教育意义,因为我计划重构这些应用程序以使用连接池,但我现在正在寻找一个快速的创可贴。
最佳答案
关闭的重要部分是数据库端发生的事情。 RDBMS 必须关闭该连接。调用 close() 方法会将消息传达给数据库以关闭连接。
将连接设置为 null 不会指示 RDBMS 执行任何操作。
同样的逻辑适用于ResultSet(数据库端的游标)和Statement。您需要按照创建的相反顺序,在创建它们的方法的finally block 中的各个try/catch block 中关闭它们。否则,您将看到有关“超出最大光标数”的错误。
关于java - Java 应用程序中 Oracle 连接未关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3773212/