我希望有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 秒来确定连接是否坏了吗?
非常感谢,提前。