【问题标题】:How are JDBC connections implemented?JDBC 连接是如何实现的?
【发布时间】:2015-01-31 13:24:20
【问题描述】:

我有一个项目,我在其中使用 HikariCP 进行 JDBC 连接池。 HikariCP 非常适合我的需求。它还记录池的统计信息,如下所示。

2014-12-03 10:16:08 DEBUG HikariPool:559 - Before cleanup pool stats loginPool (total=8, inUse=0, avail=8, waiting=0)
  2014-12-03 10:16:08 DEBUG HikariPool:559 - After cleanup pool stats loginPool (total=7, inUse=1, avail=7, waiting=0)

仅出于实验目的,我使用MySQL Workbench 关闭了已配置数据库的所有MySQL 连接。但是,我仍然看到HikariCP 像以前一样记录统计信息,尽管没有与数据库的实际连接。当有连接请求时,它会立即建立连接(初始 8 个),所以一切正常。

那么,我的问题是如何管理或实施这些连接?我认为HikariCP 记录统计信息的原因,就好像有连接一样,是因为它在内存中对连接的引用是有效的,而这些实际上是不存在的(带有数据库)。

我的理解正确吗?

【问题讨论】:

    标签: java database jdbc connection-pooling hikaricp


    【解决方案1】:

    当您使用 MySQL Workbench 关闭连接时,您将在服务器端关闭它们。在 JDBC(客户端)端,之前建立的连接将一直存在,直到客户端代码尝试使用它们。到那时,就会发现它们“坏了”;即客户端在尝试使用它们时会得到异常。

    客户端 JDBC 连接对象只有在您的 Java 应用程序代码返回到连接池时才会关闭或回收。

    【讨论】:

    • 只是好奇。我已经承认这个问题很广泛。但是,有什么资料可以用来理解 Java Heap 对象和外部连接之间的联系吗?
    • 你需要的是 MySQL Connector/J 和 HikariCP 的源代码。深入研究 JVM 源代码不太可能告诉您任何相关信息。 (在那个级别上,这只是映射到套接字和流,不太可能进行任何与您在 JDBC 客户端 API 上观察到的内容相关的“管理”。)
    【解决方案2】:

    连接池在启动时创建了 8 个连接。您说您使用工作台断开了它们的连接。大多数连接池在使用之前不会知道连接已断开连接。

    你的假设是正确的。您手动终止了连接,但池有一个它假定已连接的 8 个套接字的句柄。给定时间,您的连接池可能已经检查了连接的有效性并尝试重新连接它们。我不能代表 HikariCP,但这就是现代连接池所做的。

    【讨论】:

    • 谢谢。但是,我最感兴趣的是内部工作。这些是如何管理的?
    • 嗯..解释“托管”?连接池的目的是从池返回的连接中抽象出实际的 JDBC 连接。他们可以做一些事情,例如创建准备好的语句,然后尽可能在同一连接上执行后续语句。您的代码看到的 Connection 对象与实际连接之间可能没有一对一的关系,具体取决于池如何优化它们。 “他们是怎么管理的?”是个大问题。
    • 是的。我意识到我的错误。这个问题其实很广泛。
    • JDBC 连接池不会处理本机代码和套接字。 JDBC 驱动程序可能,但池只是位于驱动程序之间。 JDBC驱动返回的Connection接口和连接池返回的一样。因此,它将查询传递给驱动程序,就好像它们直接来自您的代码一样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-04
    相关资源
    最近更新 更多