【问题标题】:Question regarding org.apache.commons.dbcp.BasicDataSource关于 org.apache.commons.dbcp.BasicDataSource 的问题
【发布时间】:2011-05-05 21:11:51
【问题描述】:

我修复了一些与我们使用 BasicDataSource 的方式相关的错误,尽管我了解其中的一部分,但我仍有一些问题没有得到解答 :)

问题: 数据库故障后,应用程序无法自动连接到数据库。

应用程序正在使用org.apache.commons.dbcp.BasicDataSource class 作为与 Oracle 数据库的 JDBC 连接的 TCP 连接池。

修复: 经过一番研究,我发现在 BasicDataSource testOnBorrow 和 testOnreturn 没有设置。我提供了验证查询来测试连接。这解决了问题

池中的最大连接数设置为 1

我的理解: 连接池会将连接移交给应用程序。 我认为正在发生的是应用程序 MAGICALLY 在数据库崩溃时将错误集合返回到池中。现在,由于 Pool 不知道它是否是一个错误的连接,它会在下次需要它时将相同的连接移交给应用程序,从而导致应用程序不会自动重新连接到 db。

现在,在修复之后.. 每当错误的连接返回到连接池时,由于我在上面所做的修复,它将被丢弃并且不会再次使用。

现在我知道 BasicDataSource 在提供给应用程序之前包装了连接,这样每当应用程序说 con.close ..BasicDataSource 就会知道该连接不再被使用..它会负责将连接返回到池或丢弃等。

未回答的问题: 但是我不明白是什么让应用程序 MAGICALLY 在连接中断时将连接返回到连接池[请注意,当连接不正常退出时不会调用 con.close 方法]。 BasicDataSource 无法知道连接已关闭或存在?有人可以指点我为此编写代码吗?

我的总体理解是为什么修复有效??

【问题讨论】:

    标签: apache jdbc apache-commons apache-commons-dbcp


    【解决方案1】:

    现在,我知道这是一个老话题,但它在谷歌搜索结果中的排名很高,所以我想我可以给它一个快速的答案。有关配置 BasicDataSource 的更多信息,您应该参考 DBCP 配置页面:http://commons.apache.org/proper/commons-dbcp/configuration.html

    回答“BasicDataSource 如何知道连接何时被放弃并需要返回连接池?”的“未回答”问题? (转述)...

    org.apache.commons.dbcp.BasicDataSource 能够通过使用连接的包装类来监控它提供的连接的流量和使用情况。每次调用连接上的方法或从连接创建的任何语句时,实际上都是在调用实现接口或使用相同方法扩展基类的包装类(多态万岁!)。这些自定义方法允许 DataSource 知道 Connection 是否处于活动状态。

    在 BasicDataSource 本身上,有一个名为“removeAbandoned”的属性和另一个名为“removeAbandonedTimeout”的属性,用于配置将放弃的连接返回到连接池的行为。

    "removeAbandoned" 是一个布尔值,指示是否应将放弃的连接返回到池中。默认为“假”。

    "removeAbandonedTimeout" 是一个 int,表示在认为放弃连接之前应该允许经过的不活动秒数。默认值为 300(约 5 分钟)。

    【讨论】:

      【解决方案2】:

      查看test for abandoned connections,似乎当池中的所有连接都“正在使用”时,当请求新连接时,“正在使用”的连接会被测试放弃(它们维护上次使用的时间戳时间)。

      BasicDataSource#setRemoveAbandoned(boolean)BasicDataSource#setRemoveAbandonedTimeout(int)

      无论您的连接池在关闭废弃连接方面有多聪明,您都应该始终确保每个连接都在 finally 块中关闭,例如:

      Connection conn = getConnection();
      try {
          ... // perform work
      } finally {
          conn.close();
      }
      

      或者使用Apache DBUtils等其他方式。

      【讨论】:

      • 我同意。我的观点是,当应用程序崩溃时,JVM 可能没有机会执行 conn.close()。
      • 我觉得这里放弃的意思是[idol for x time]。在这种情况下,应用程序[不断重试]应该总是[最终]获得健康的连接,因为放弃的连接被删除。这没有发生。我认为由于某种原因,在特定超时后,连接池只会将连接带回池中,如果偶像而不管数据库是否关闭,并将其移交给应用程序。
      猜你喜欢
      • 2021-11-29
      • 2011-09-22
      • 2018-05-23
      • 2011-11-16
      • 2021-03-27
      • 2017-01-27
      • 2011-10-31
      • 2011-01-19
      • 2011-07-20
      相关资源
      最近更新 更多