JDBC 连接池:连接重用?
根据我的理解,JDBC 连接池(在基本层面上)是这样工作的:
- 在应用程序初始化期间创建连接并放入缓存中,
- 根据需要向应用程序提供这些缓存的连接,
- 一个单独的线程维护连接池,执行以下活动:
- 丢弃已使用(关闭)的连接
- 创建新连接并将其添加到缓存中以维持特定的连接数量
但是,每当我在 JDBC 连接池讨论中听到术语“连接重用”时,我都会感到困惑。什么时候会发生连接重用?
这是否意味着连接池为两个不同的数据库交互提供了相同的连接(而不关闭它)?或者,即使在数据库调用后关闭连接,是否有办法继续使用连接?
As per my understanding, JDBC Connection Pooling (at a basic level) works this way:
- create connections during app initialization and put in a cache
- provide these cached connections on demand to the app
- a separate thread maintains the Connection Pool, performing activities like:
- discard connections that have been used (closed)
- create new connections and add to the cache to maintain a specific count of connections
But, whenever I hear the term "connection reuse" in a JDBC Connection Pooling discussion, I get confused. When does the connection reuse occurs?
Does it means that Connection Pool provides the same connection for two different database interactions (without closing it)? Or, is there a way to continue using a connection even after it gets closed after a DB call?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
连接池通过重用连接来工作。应用程序从池中“借用”连接,然后在完成后“归还”它。然后,该连接会再次分发给应用程序的另一部分,甚至分发给不同的应用程序。
只要同一个连接不被两个线程同时使用,这就是完全安全的。
连接池的关键点是尽可能避免创建新连接,因为这通常是一项昂贵的操作。重用连接对于性能至关重要。
Connection pooling works by re-using connections. Applications "borrow" a connection from the pool, then "return" it when finished. The connection is then handed out again to another part of the application, or even a different application.
This is perfectly safe as long as the same connection is not is use by two threads at the same time.
The key point with connection pooling is to avoid creating new connections where possible, since it's usually an expensive operation. Reusing connections is critical for performance.
连接池不向您提供来自驱动程序的实际连接实例,而是返回一个包装器。当您对池中的 Connection 实例调用“close()”时,它不会关闭驱动程序的 Connection,而只是将打开的连接返回到池中,以便可以重新使用它(请参阅 skaffman 的答案)。
The connection pool does not provide you with the actual Connection instance from the driver, but returns a wrapper. When you call 'close()' on a Connection instance from the pool, it will not close the driver's Connection, but instead just return the open connection to the pool so that it can be re-used (see skaffman's answer).
连接池重用连接。
下面是 apache dbcp 的工作原理。
Apache DBCP 实现返回 PoolableConnection 类型的连接包装器。
PoolableConnection.close() 检查实际的底层连接是否关闭,如果没有关闭,则将此 PoolableConnection 实例返回到连接池(在本例中为 GenericObjectPool)。
Connection pooling reuses connections.
Here is how apache dbcp works underline.
Apache DBCP implementation returns connection wrapper which is of type PoolableConnection.
PoolableConnection.close() inspects if actual underlying connection is closed or not, if not then it returns this PoolableConnection instance into connection pool (GenericObjectPool in this case).
我的理解与上面所述相同,并且由于错误,我有证据表明它是正确的。在我使用的应用程序中存在一个错误,即 SQL 命令的列名无效。执行时会抛出异常。如果连接关闭,那么下次获取并使用连接时,这次使用正确的 SQL,将再次引发异常,并且错误消息与第一次相同,尽管不正确的列名甚至不会出现在第二个SQL。所以连接显然被重用了。如果在抛出第一个异常后连接未关闭(由于列名错误),则下次使用连接时一切正常。据推测,这是因为第一个连接尚未返回到池中以供重用。 (此错误发生在 Jave 1.6_30 和连接到 MySQL 数据库的情况下。)
My understanding is the same as stated above and, thanks to a bug, I have evidence that it's correct. In the application I work with there was a bug, an SQL command with an invalid column name. On execution an exception is thrown. If the connection is closed then the next time a connection is gotten and used, with correct SQL this time, an exception is thrown again and the error message is the same as the first time though the incorrect column name doesn't even appear in the second SQL. So the connection is obviously being reused. If the connection is not closed after the first exception is thrown (because of the bad column name) then the next time a connection is used everything works just fine. Presumably this is because the first connection hasn't been returned to the pool for reuse. (This bug is occurring with Jave 1.6_30 and a connection to a MySQL database.)