我修复了一些与我们使用BasicDataSource的方式相关的错误,虽然我理解其中的一部分但仍然有一些问题没有答案:)
问题: 数据库失败后,应用程序无法自动连接到数据库。
应用程序使用org.apache.commons.dbcp.BasicDataSource class作为与Oracle db的JDBC连接的TCP连接池。
修正: 经过一番研究后我发现在BasicDataSource中没有设置testOnBorrow和testOnreturn。我提供了验证查询来测试连接。这解决了问题
池中的最大连接数未设置为1
我的理解: 连接池将移交与应用程序的连接。 我认为发生的事情是应用程序 MAGICALLY 在db崩溃时将坏集合返回到池中。现在,由于Pool不知道它是否是一个错误的连接,它会在下次需要时将相同的连接移交给应用程序,导致应用程序不自动重新连接到db。
现在,在修复之后..每当一个错误的连接返回到连接池时,它将被丢弃并且不会再次使用,因为我在上面做了修复。
现在我知道BasicDataSource在提供给应用程序之前包装了连接,这样每当应用程序说con.close时..BasicDataSource就会知道连接不再被使用..它将负责将连接返回到游泳池或丢弃等。
未答复的问题: 但是,我不明白的是,什么使应用程序 MAGICALLY 在连接池断开时返回连接[注意,当连接不正常地退出时不调用con.close方法]。 BasicDataSource无法知道连接已关闭或存在?。有人能指出我的代码吗?
我的整体理解是为什么修复有效?
答案 0 :(得分:4)
现在,我知道这是一个旧帖子,但谷歌搜索结果很高,所以我想我可以快速给出答案。有关配置BasicDataSource的更多信息,请参阅DBCP配置页面:http://commons.apache.org/proper/commons-dbcp/configuration.html
回答“未解决的”问题“BasicDataSource如何知道什么时候连接被放弃并需要返回到连接池?” (转述)...
org.apache.commons.dbcp.BasicDataSource能够通过使用Connection的包装类来监视它提供的连接上的流量和使用情况。每次调用连接上的方法或从连接创建的任何语句时,实际上都在调用实现接口的包装类或使用相同的方法扩展基类(Hurray for Polymorphism!)。这些自定义方法允许DataSource知道Connection是否处于活动状态。
在BasicDataSource本身,有一个名为“removeAbandoned”的属性和另一个名为“removeAbandonedTimeout”的属性,用于配置将连接池的abondonded连接返回的行为。
“removeAbandoned”是一个布尔值,指示是否应将已放弃的连接返回到池中。默认为“false”。
“removeAbandonedTimeout”是一个int,表示在认为连接被放弃之前应该允许通过的不活动秒数。默认值为300(约5分钟)。
答案 1 :(得分:0)
查看test for abandoned connections,当请求新连接时,当池中的所有连接都“正在使用”时,“正在使用”连接将被测试是否被放弃(它们保持时间戳为上次使用的时间)。
请参阅BasicDataSource#setRemoveAbandoned(boolean)和BasicDataSource#setRemoveAbandonedTimeout(int)
无论您的连接池在关闭废弃连接时有多聪明,都应该始终确保在finally块中关闭每个连接,例如:
Connection conn = getConnection();
try {
... // perform work
} finally {
conn.close();
}
或使用其他方法,例如Apache DBUtils。