繁体   English   中英

Java连接未在Java Application中关闭

[英]Oracle connection not closing in Java Application

我在一些不使用连接池的旧Java Web应用程序中发生连接泄漏。 试图找到泄漏很难,因为IT不会授予我访问v $ session SELECT Count(*) FROM v$session;

所以我试图使用System.out语句进行调试。 即使在关闭连接conn.close(); 当我将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 = null; conn.close();下面conn.close(); 声明连接现在似乎已关闭。 所以我的问题是conn.close(); 实际上释放我的连接或我也必须使它为null以真正释放我的连接。 就像我说的那样,我很难确定连接是否实际发布而无法查询v $ session。 有没有java代码片段可以给我打开连接?

这可能是教育性的,因为我计划重构这些应用程序以使用连接池,但我现在正在寻找一个快速的绑定。

关闭的重要部分是数据库方面正在发生的事情。 这是必须关闭该连接的RDBMS。 调用close()方法是将消息传递给数据库以关闭连接的方法。

将连接设置为null不会指示RDBMS执行任何操作。

相同的逻辑适用于ResultSet,它是数据库端的游标和Statement。 您需要以创建它们的相反顺序关闭创建它们的方法的finally块中的各个try / catch块中的那些块。 否则,您将看到有关“超出最大游标数”的错误。

将conn设置为null只会断开连接对象的引用链接,并且不会影响正在打开的连接。 如果连接仍处于打开状态,则仍将从JDBC驱动程序/连接池等内部引用连接...

将变量设置为null更能说明垃圾收集器可以在需要时清除原始对象,而不是其他任何东西。

正如其他人所说,这里有两个不同的概念:关闭连接并跟踪变量中的连接。

要关闭连接,请调用conn.close() 不会将变量conn设置为null。 您可以使用conn.isClosed()测试连接是否已打开。



如果您不再需要跟踪代码中的连接,则可以conn = null 不会立即关闭连接。 我相信连接将根据JDBC 文档自动关闭:

立即释放此Connection对象的数据库和JDBC资源,而不是等待它们自动释放。

如果您选择这条路线,请注意垃圾收集器可能无法尽快关闭您的连接,并且您可能看到资源泄漏; 在连接被垃圾回收之前,不会释放保留的数据库锁。 某些驱动程序(我不知道oracle是否为1)对一次可能存在的连接数施加了最大限制,因此保留打开的连接也会导致程序中的连接失败。

连接泄漏是最好的。 我认为一个好的策略是在几个函数中包含连接的获取和释放,然后总是通过这些函数获取和释放连接。 然后,您可以让这些函数维护所有打开的连接的列表,并在allocate函数的调用者上执行堆栈跟踪。 然后有一个屏幕,显示所有打开的连接列表以及它们来自何处。 在测试环境中运行它,使用一堆屏幕运行,然后全部退出以便所有连接应该关闭,然后调出显示打开connectoins的屏幕,并显示反派。

我在这里的解释是一个有根据的猜测。

作为一种做法,我总是在收盘后设置conn = null。 我相信当你做conn.close()时,你告诉垃圾收集器它已经准备好被垃圾收集了。 但是,将由垃圾收集过程决定何时这样做。

你也可以改变你的

如果(参数conn!= NULL)

if(conn.isClosed())

..

是否有Java代码片段可以给我打开连接?

Statement smt = null;
    ResultSet rs = null;
    try { 
        // Create Statement from connection
        smt = conn.createStatement();
        // Execute Query in statement 
        rs = stmt.executeQuery("SELECT 1 FROM Dual");

        if (rs.next()) {
            return true; // connection is valid
        }
        catch (SQLException e) {
            // Some sort of logging
            return false;
        }
        finally {
            if (smt != null) smt.close();
            if (rs != null) rs.close();
        }

只是快速猜测,假设您使用的是Oracle。 Sugession:为什么不安装jboss并通过那里设置连接池?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM