关于 org.apache.commons.dbcp.BasicDataSource 的问题
我修复了一些与我们使用 BasicDataSource 的方式相关的错误,尽管我理解了其中的一部分,但我仍然有一些问题没有得到解答:)
问题: 数据库发生故障后,应用程序无法自动连接到数据库。
应用程序正在使用 org.apache.commons.dbcp.BasicDataSource 类 作为与 Oracle 数据库的 JDBC 连接的 TCP 连接池。
修复: 经过一番研究,我发现在 BasicDataSource 中未设置 testOnBorrow 和 testOnreturn 。我提供了验证查询来测试连接。 问题
这解决了池中最大连接数设置为 1 的
我的理解: 连接池会将连接移交给应用程序。 我认为正在发生的事情是应用程序在数据库崩溃时神奇地将错误的集合返回到池中。现在,由于池不知道它是否是一个坏连接,它会在下次需要时将相同的连接移交给应用程序,从而导致应用程序不会自动重新连接到数据库。
现在,修复后..每当错误的连接返回到连接池时,由于我上面所做的修复,它将被丢弃并且不会再次使用。
现在我知道 BasicDataSource 在提供给应用程序之前包装连接,这样每当应用程序说 con.close ..BasicDataSource 就会知道该连接不再使用..它将负责将连接返回到池或Discardigg 等
未回答的问题: 然而,我不明白的是,是什么让应用程序在连接断开时神奇地将连接返回到连接池[请注意,当连接不正常退出时,不会调用 con.close 方法]。 BasicDataSource 无法知道连接已关闭还是存在?。有人可以指点我为此编写代码吗?
我的总体理解是为什么修复有效?
I fixed some bug related to the way we were using BasicDataSource and though I understand part of it I still have some questions unanswered :)
Problem:
The application was not able to auto-connect to the database after a db failure.
Application is using org.apache.commons.dbcp.BasicDataSource class as a TCP-connection pool for a JDBC connection to Oracle db.
Fix:
After some research I discovered that in BasicDataSource testOnBorrow and testOnreturn were not set. I provided the validation query to test connections. This fixed the problem
Max no of connections in pool was set to 1
My Understanding:
The connection pool would hand over a connection to the application.
What I think was happening was the application MAGICALLY returned the bad collection to the pool when it db crashed . Now since the Pool does not know if it is a bad connection it would hand over the same connection to the application next time it needs it causing the application to not auto-reconnect to db.
Now, after the fix.. whenever a bad connection is returned to the connection pool it would be discarded and wont be used again because of the fix I made above.
Now I know that BasicDataSource wraps the connection before giving to the application, such that whenever application says con.close ..BasicDataSource would know that the connection is not used any more.. it will take care of either returning the connection to the pool or discardigg etc.
Unanswered Question:
However what I do not understand is what makes the application MAGICALLY return the connection to the connection pool when its broken[Note that con.close method is not called when the connection exits un-gracefully]. There is no way of BasicDataSource to know that the connection closed or there is ?. Can someone point me to code for that ?
I my overall understanding connect of why the fix worked ??
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
现在,我知道这是一个旧线程,但它在谷歌搜索结果中的排名很高,所以我想我可以给它一个快速的答案。有关配置 BasicDataSource 的更多信息,您应该参考 DBCP 配置页面:http:// /commons.apache.org/proper/commons-dbcp/configuration.html
回答“BasicDataSource 如何知道连接何时被放弃并需要返回到连接池?”这一“未答复”的问题。 (解释)...
org.apache.commons.dbcp.BasicDataSource 能够通过使用连接的包装类来监视其提供的连接上的流量和使用情况。每次您调用连接上的方法或从连接创建的任何语句时,您实际上是在调用一个包装类,该包装类实现了一个接口或使用这些相同的方法扩展了一个基类(多态万岁!)。这些自定义方法允许数据源知道连接是否处于活动状态。
在 BasicDataSource 本身上,有一个名为“removeAbandoned”的属性和另一个名为“removeAbandonedTimeout”的属性,用于配置将废弃的连接返回到连接池的行为。
“removeAbandoned”是一个布尔值,指示是否应将废弃的连接返回到池中。默认为“假”。
“removeAbandonedTimeout”是一个 int,表示在认为放弃连接之前应允许经过的不活动秒数。默认值为 300(大约 5 分钟)。
Now, I know that this is kind of an old thread, but it's high on google search results, so I thought I might give it a quick answer. For more information on configuring the BasicDataSource, you should reference the DBCP Configuration page: http://commons.apache.org/proper/commons-dbcp/configuration.html
To answer the "unanaswered" question of "How does BasicDataSource know when a connection is abondoned and needs to be returned to the connection pool?" (paraphrased)...
org.apache.commons.dbcp.BasicDataSource is able to monitor traffic and usage on the connections it offers by using a wrapper class for the Connection. Every time you call a method on the connection or any Statements created from the connection, you are actually calling a wrapper class that implements an interface or extends a base class with those same methods (Hurray for Polymorphism!). These custom methods allow the DataSource to know whether or not a Connection is active.
On the BasicDataSource itself, there is a property called "removeAbandoned" and another called "removeAbandonedTimeout" that are used to configure this behavior of returning abondonded connections to the connection pool.
"removeAbandoned" is a boolean that indicates whether abandoned connections should be returned to the pool. Defaults to "false".
"removeAbandonedTimeout" is an int, that represents the number of seconds of inactivity that should be allowed to pass before a connection is considered to be abandoned. Default value is 300 (about 5 minutes).
查看废弃连接测试 ,看起来当请求新连接时池中的所有连接都“正在使用”时,“正在使用”的连接将被测试是否被放弃(它们维护上次使用时间的时间戳)。
请参阅 BasicDataSource#setRemoveAbandoned(boolean) 和 BasicDataSource# setRemoveAbandonedTimeout(int)
无论您的连接池在关闭废弃连接方面有多聪明,您都应该始终确保每个连接在finally块中关闭,例如:
或者使用其他一些方法,例如Apache DBUtils。
Looking at the test for abandoned connections, it appears that when all connections in the pool are "in use" when a new connection is requested, the "in-use" connections are tested for abandonment (they maintain a timestamp of last used time).
See BasicDataSource#setRemoveAbandoned(boolean) and BasicDataSource#setRemoveAbandonedTimeout(int)
Regardless of how clever or not your connection pool is in closing abandoned connections, you should always ensure each connection is closed in a finally block, e.g.:
Or use some other means such as Apache DBUtils.