1

我希望有C3P0方面的专家可以帮助我回答以下问题。

首先,这是我要解决的一般问题。我们有一个连接到数据库的应用程序。当数据库关闭时,请求开始需要几秒钟的时间来处理,而不是几毫秒。这是因为 C3P0 将尝试创建到数据库的新连接。它最终会超时并且请求将被拒绝。

我想出了一个修复它的建议。在从池中获取连接之前,我将查询 C3P0 的 API 以查看池中是否有任何连接。如果没有,我们将立即放弃该请求。这样,我们的延迟应该保持在毫秒内,而不是等到超时发生。该解决方案之所以有效,是因为 C3P0 能够在检测到连接变坏时删除连接。

现在,我使用“setTestConnectionOnCheckin”和“setTestConnectionOnCheckout”的值为“false”设置了一个测试。根据我的理解,这意味着 C3P0 不会测试连接(或者,比如说,正在使用的连接,因为还有 idleConnectionTestPeriod 设置)。但是,当我运行测试时,关闭数据库后,C3P0 会立即检测到它并从池中删除连接。为了给你一个更清晰的画面,这里是执行的结果:

14:48:01 - 请求成功处理。处理时间:5 毫秒。14:48:02 - 请求成功处理。处理时间:4 毫秒。14:48:03 - (此时数据库已关闭)。14:48:04 - java.net.ConnectException。14:48:05 - 请求被拒绝。处理时间:258 毫秒。14:48:06 - 请求被拒绝。处理时间:1 毫秒。14:48:07 - 请求被拒绝。处理时间:1 毫秒。

C3P0 显然知道数据库出现故障并从池中删除了连接。这可能需要一段时间,因为关闭数据库后的第一个请求比其他请求花费的时间更长。我已经多次运行此测试,单个请求可能需要 1 毫秒到 3.5 秒(这是超时时间)。此条目出现的次数与我为池定义的连接数一样多。为简单起见,我省略了所有其余部分。

我认为 C3P0 能够立即从池中删除连接(嗯,在上面的示例中最快 258 毫秒),但我很难解释其他人为什么这样做。如果“setTestConnectionOnCheckin”和“setTestConnectionOnCheckout”设置为“false”,C3P0 怎么知道连接坏了?

即使它们设置为“true”,测试连接也应该尝试在数据库上执行查询(类似于“select 1 + 1 from dual”)。我们数据库宕机了,测试不应该超时吗?换句话说,C3P0 不应该花 3.5 秒来确定连接是否坏了吗?

非常感谢,提前。

4

1 回答 1

0

(抱歉......这会很简洁,我正在打电话。)

1) 即使没有配置明确的连接测试,c3p0 也会测试在签出时遇到异常的连接,以确定它们是否仍然适合池化。

2) 如果 DBMS 不可用,一个好的 JDBC 驱动程序会很快抛出异常。这些内部连接测试没有理由变慢。

3)而不是轮询未使用的连接以避免等待检查/新的获取,您可以考虑只设置配置参数 checkoutTimeout。

祝你好运!

于 2013-10-08T05:08:02.100 回答