2010-06-21 158 views
14

按我的理解,JDBC连接池(在一个基本水平)的工作原理是这样的:JDBC连接池:连接重用?

  1. 创建应用程序初始化过程中的连接,并将在缓存
  2. 提供给应用程序的需求,这些缓存的连接
  3. 一个单独的线程保持连接池,执行类似的活动:已经使用
    • 丢弃连接(关闭)
    • 创建新的连接S和添加到缓存中保持连接

但是,每当我在一个JDBC连接池的讨论听到“连接复用”,我感到困惑的具体数量。连接重用何时发生?

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

+0

只是好奇,但哪个连接池库启动单独的线程管理池?我不认为commons-dbcp这样做 - 至少不是BasicDataSource。相反,我认为连接检查是在连接从池中检出时完成的 – 2010-06-21 11:57:04

回答

12

连接池通过重新使用连接起作用。应用程序从池中“借用”连接,然后在完成时“返回”它。然后再将连接分发给应用程序的另一部分,甚至是另一个应用程序。

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

连接池的关键是避免在可能的情况下创建新的连接,因为它通常是一个昂贵的操作。重用连接对性能至关重要。

10

连接池不会为驱动程序提供实际的Connection实例,但会返回一个包装。当你从一个Connection实例中调用'close()'时,它不会关闭驱动程序的Connection,而只是将打开的连接返回到池中,以便它可以被重用(参见skaffman的回答)。

+2

这取决于您使用的连接池的具体类型,例如, 'DataSource'或Commons DBCP-style。轻量级池可以返回原始的'Connection',并依赖不调用'close()'的应用程序代码。 – skaffman 2010-06-21 09:46:21

+0

那么,这是否意味着池中的JDBC连接必须依赖于Connection.commit()或Connection.setAutoCommit(true) - 可能这些调用是在Connection wrapper的over-ridden close()中进行的。 – haps10 2010-06-21 09:59:02

-1

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

+3

请避免使用文字墙,强烈建议在SO上格式化。 – Azulflame 2012-11-15 21:05:03

+0

除了格式化之外,考虑添加你发出的SQL命令,只要你得到的错误是为了丰富你的答案 – 2012-11-15 21:06:30

1

连接池重用连接。 以下是apache dbcp如何工作的下划线。

Connection poolableConnection= apacheDbcpDataSource.getConnection(); 

阿帕奇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 
.... 
       }