【问题标题】:If a JDBC Connection object's scope is local, does it need to be explicitly closed? (MySQL database used)如果 JDBC Connection 对象的作用域是本地的,是否需要显式关闭它? (使用 MySQL 数据库)
【发布时间】:2026-01-06 16:20:02
【问题描述】:

我有一个Connection 类型的方法。一旦连接到数据库,它就会返回Connection 值。代码如下:

public Connection establishConnection()  
{

    Connection conn = null;
    try 
    {
        this.readLogin();  // prompts user to input for user, pass and host variables using Scanner class
        this.createDatabaseIfNeeded();  // creates chessleaguedb if not found     
        conn = DriverManager.getConnection
                    ("jdbc:mysql://"+host+":3306/chessleaguedb", user, pass);
        System.out.println("Successfully connected to chessleaguedb");

    } 
    catch (SQLException z ) 
    {
        // logic
    }   
    return conn;
}

然后我在我的菜单类中创建这个方法类的实例;调用上述方法并将其返回值传递给菜单类中的 Connection 对象(我这样做只是为了保持整洁,并希望遵守良好的 OO 设计原则):

DatabaseConnection startConnection = new DatabaseConnection();  // class the above method is located in
Connection connect = startConnection.establishConnection();

我的问题是:因为在上述方法中打开了一个活动连接,我是否需要在该方法中显式关闭它?还是因为那个方法中的Connection对象是本地的,方法结束后就不存在了,有必要吗?我无法关闭它,因为在return conn; 之后调用相关的关闭方法会在 NetBeans 中给我一个无法访问的语句错误。编辑* 我不能使用 Pooling 而不是 Java EE,也不能使用开源软件来处理它,因为工作必须是我自己的,因为这是大学工作(第二年)。

【问题讨论】:

    标签: java mysql jdbc


    【解决方案1】:

    Connection 实现 AutoCloseable。

    我会使用 try-with-resources 范例,因为它会自动关闭资源,无需显式关闭资源。

    try(Connection connect = startConnection.establishConnection()){
    
    }catch(SQLException e) {
       e.printStackTrace();
       return("failed");
     }
    

    有关使用 JDBC 对象的 try-with-resources 的更多信息可以找到 here

    try-with-resources 的一般信息可以在here找到

    【讨论】:

    • 很有趣,“连接实现了 AutoCloseable”
    【解决方案2】:

    是的,您需要在DatabaseConnection class 中编写和处理closeConnection(),否则会在应用程序中造成连接泄漏。很快,您的应用程序将耗尽连接。

    您需要确保在您调用 establishConnection() 的同一方法的 finally 块中调用下面的 closeConnection(),否则资源 (connection) 将逃逸(导致泄漏)。

    public void closeConnection(Connection conn) {
       try {
            conn.close();
       } catch(SQLException sqlexe) {
         // Connection closing failed
        //Log exception
      }
    }  
    

    但是,像这样显式处理连接并不是最佳做法,而是尝试使用连接池机制。

    您可以查看here 的连接池。

    【讨论】:

    • 正是我需要知道的。
    • 这里的重要一点是,当变量超出范围时没有什么神奇的。他们最终可能会被 GCed,但仅此而已;锁没有被释放,连接没有返回到池中,Closeables 被关闭,等等。
    • @javaguy 欣赏代码。如果我在方法中的 return 语句之后调用“conn.closeConnection()”,它会给我一个无法访问语句的错误。也许这首先是我的糟糕设计,但是我应该如何在返回 Connection 值的方法中关闭它?
    • 我们需要确保 closeConnection() 是从 finally 块调用的,在该块中调用了方法establishConnection()。
    • @javaguy 完成,现在排序。回复:汇集。应该提到的问题。本科二年级,不使用Java EE,不允许使用开源软件处理池,因为工作必须是我自己的。
    【解决方案3】:

    你需要显式关闭连接。最好创建一个Finally块并通过conn.close()关闭连接;

    【讨论】:

      【解决方案4】:

      您必须关闭连接对象,否则它会创建连接泄漏,这可能会使您的数据库服务器崩溃。

      本地作用域限制了连接对象的使用,不会减少生命周期。

      【讨论】:

        【解决方案5】:

        您应该关闭连接,但绝对不需要,因为之前或之后它将被 jvm 关闭。但是你不知道什么时候,所以你可能会遇到连接泄漏或内存问题。 但是,您应该检查您的架构。每次连接到 db 会非常慢、容易出错并且消耗资源。尝试使用连接池或至少以安全的方式重用您打开的连接

        【讨论】:

        • 也可能是驱动程序(或连接池)的某些其他部分在未明确关闭时会保留连接,因此永远不会释放连接。
        最近更新 更多