为什么我们应该在JDBC中关闭连接?如果不这样做,会发生什么?

8

在Java中与数据库通信时,我们通常遵循以下步骤:

  1. 加载驱动程序
  2. 获取连接
  3. 创建语句或PreparedStatement
  4. 获取ResultSet
  5. 关闭连接

我很困惑为什么要关闭连接,因为大家都说创建连接很耗费资源,所以我们不能这样做吗:

static
    {
        try
        {
            connection = DriverManager.getConnection(connectorURL,
                    user, password);
        } catch (SQLException e)
        {
            e.printStackTrace();
        }
    }

我们只需创建一个单例连接,并在任何地方使用它。是这样吗?如果我像这样使用它,会发生什么?
如果我不关闭连接会发生什么?
另外,我们将使用一个连接池,它将在池中创建一些连接,我们从池中获取连接,池中的连接也不会关闭,那么为什么如果我们不使用连接池,就需要遵循步骤并关闭连接呢?
这很困惑,我不知道原理。请帮助我。谢谢。

1
即使使用连接池,您也必须关闭连接:这会向连接池发出信号,表明它可以重新使用。您存储在静态变量中的解决方案真的很糟糕:它可能会引起各种难以调试的并发问题。如果您担心连接创建的成本,则应使用连接池,而不是通过DriverManager创建连接。 - Mark Rotteveel
1
你可以执行你所写的代码,但连接不是线程安全的,所以这是毫无意义的,除非你也要引入同步,而这种治疗方法比病还要严重。最好使用线程池来为你提供一个本地变量作为“Connection”,并在方法退出时关闭它以将其返回到池中。如果你不关闭它,它会泄漏,并占用服务器资源。 - user207421
@EJP 连接本身可能是线程安全的(JDBC所需),但应用程序对连接的使用可能不是线程安全的。考虑到不同的事务隔离级别、边界(提交/回滚/自动提交)等因素。 - Mark Rotteveel
2个回答

13
如果我们不关闭连接,将导致连接内存泄漏。即使用户退出,连接仍然保持活动状态,直到应用程序服务器/ Web 服务器关闭。
还有其他原因。假设数据库服务器有10个可用连接,而10个客户端请求连接。如果数据库服务器授予所有请求,并且在使用后未关闭它们,则数据库服务器将无法为另一个请求提供其他连接。出于这个原因,我们需要关闭它们-这是强制性的。
此外,它可能会导致与数据库完整性有关的一些恶意活动。

3
我们只需创建一个单例作为连接,然后在任何地方都可以使用它。这样做怎么样?如果按照这种方式使用,会发生什么?
在这种情况下,你只有一个数据库连接。如果数据库查询执行时间较长,则等待该连接对象的其他请求也必须等待。因此,这不是一种推荐的方法。
如果我不关闭连接会发生什么?
通过关闭连接,StatementResultSet 对象将自动关闭。使用close()方法来关闭连接。如果你忘了这样做,就会导致连接内存泄漏。例如:假设你的应用程序有10个数据库连接,并且同时有10个用户活跃。之后,3个用户退出应用程序,但因为没有实现连接关闭机制,这3个连接仍然处于活跃状态,结果你的应用程序将无法向其他用户提供任何其他连接。此外,打开的连接数量在数据库服务器中增加会减慢应用程序的速度。所以,立即释放Connection对象的数据库和JDBC资源,而不是等待它们自动释放。
另外,我们将使用连接池,它将在池中创建一些连接,并从池中获取连接,池中的连接也不会关闭。那么,如果我们不使用连接池,为什么需要遵循这些步骤并在不使用时关闭连接?
连接池意味着重复使用连接而不是每次请求连接时创建新的连接。 此源称:“如果系统提供连接池,则查找会返回池中可用的连接。如果系统没有提供连接池,或者池中没有可用的连接,则查找会创建一个新的连接。应用程序在不需要任何代码更改的情况下受益于连接重用。从池中重复使用的连接行为与新创建的物理连接相同。应用程序连接到数据库,数据访问按照通常的方式工作。当应用程序完成它对连接的工作时,应用程序显式地关闭连接。
池化连接上的关闭事件将信号传递给连接池模块,以便将连接放回连接池以供将来重用。”
你的应用程序从池中借用连接,使用它,然后通过关闭连接将其返回到池中。长时间处于闲置状态的自由连接不被视为问题。

3
关闭连接时,Statement和ResultSet对象将自动关闭。但并非所有的RDBMS都能做到这一点... - Yousha Aleayoub
@YoushaAleayoub 老帖子了,但你能否详细阐述一下呢? - HydroPage

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接