【问题标题】:JDBC Connection Pooling: Connection Reuse?JDBC 连接池:连接重用?
【发布时间】:2011-03-06 05:30:06
【问题描述】:

据我了解,JDBC 连接池(在基本级别)以这种方式工作:

  1. 在应用初始化期间创建连接并放入缓存中
  2. 按需向应用提供这些缓存连接
  3. 一个单独的线程维护连接池,执行如下活动:
    • 丢弃已使用的连接(关闭)
    • 创建新连接并添加到缓存中以保持特定的连接数

但是,每当我在 JDBC 连接池讨论中听到“连接重用”一词时,我都会感到困惑。连接重用什么时候发生?

是不是意味着连接池为两个不同的数据库交互提供了相同的连接(不关闭它)?或者,有没有办法在数据库调用后关闭连接后继续使用连接?

【问题讨论】:

  • 只是好奇,但哪些连接池库会启动单独的线程来管理池?我认为 commons-dbcp 不会这样做——至少 BasicDataSource 不会。相反,我认为连接检查是在从池中签出连接时完成的

标签: java jdbc connection-pooling


【解决方案1】:

连接池通过重用连接来工作。应用程序从池中“借用”一个连接,然后在完成时“归还”它。然后将连接再次分发给应用程序的另一部分,甚至是不同的应用程序。

只要不是两个线程同时使用同一个连接,这是完全安全的。

连接池的关键在于尽可能避免创建新连接,因为这通常是一项昂贵的操作。重用连接对性能至关重要。

【讨论】:

    【解决方案2】:

    连接池不会为您提供来自驱动程序的实际连接实例,而是返回一个包装器。当您在池中的 Connection 实例上调用“close()”时,它不会关闭驱动程序的 Connection,而只是将打开的连接返回到池中以便可以重复使用(参见 skaffman 的回答)。

    【讨论】:

    • 这取决于您使用的连接池的具体类型,例如DataSource 或 Commons DBCP 样式。轻量级池可以只返回原始的Connection,并依赖应用程序代码不调用close()
    • 那么,这是否意味着池中的 JDBC 连接必然依赖 Connection.commit() 或 Connection.setAutoCommit(true) - 可能这些调用是在覆盖的 close() 中进行的连接包装的。
    【解决方案3】:

    我的理解与上述相同,并且由于一个错误,我有证据证明它是正确的。在我使用的应用程序中,存在一个错误,即带有无效列名的 SQL 命令。执行时抛出异常。如果连接关闭,那么下次获取和使用连接时,这次使用正确的 SQL,再次抛出异常,错误消息与第一次相同,尽管错误的列名甚至没有出现在第二个 SQL。所以连接显然被重用了。如果在抛出第一个异常后连接没有关闭(因为列名错误),那么下次使用连接时一切正常。大概这是因为第一个连接还没有返回到池中以供重用。 (此错误发生在 Jave 1.6_30 和与 MySQL 数据库的连接中。)

    【讨论】:

    • 请避开文字墙,强烈建议在 SO 上进行格式化。
    • 除了格式化之外,只要遇到错误,考虑添加你发出的SQL命令,以丰富你的答案
    【解决方案4】:

    连接池重用连接。 下面是 apache dbcp 的工作原理。

    Connection poolableConnection= apacheDbcpDataSource.getConnection();
    

    Apache DBCP 实现返回类型为 PoolableConnection 的连接包装器。

    poolableConnection.close();
    

    PoolableConnection.close() 检查实际的底层连接是否关闭,如果没有,则将此 PoolableConnection 实例返回到连接池(本例中为 GenericObjectPool)。

    if (!isUnderlyingConectionClosed) {
                // Normal close: underlying connection is still open, so we
                // simply need to return this proxy to the pool
                try {
                    genericObjectPool.returnObject(this); //this is PoolableConnection instance in this case
    ....
                  }
    

    【讨论】:

      猜你喜欢
      • 2016-07-06
      • 2011-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-01
      • 2017-01-07
      • 2015-02-25
      • 2018-09-10
      相关资源
      最近更新 更多