0

只是寻找这段代码的基本原理解释(PoolUtiltites:2.2.4 版中的 293):

dataSource.setLoginTimeout((int) TimeUnit.MILLISECONDS.toSeconds(Math.min(1000L, connectionTimeout)));

这段代码和 setConnectionTimeout 方法意味着我得到了这种行为:

  • connectionTimeout == 0,然后 loginTimeout = Integer.MAX_VALUE
  • connectionTimeout > 0 && < 100,然后 HikariConfig 抛出 IllegalArgumentException
  • connectionTimeout >= 100 && <= 1000,则 loginTimeout = connectionTimeout
  • connectionTeimout > 1000,然后 loginTimeout = 1000

这对我来说真的很奇怪!

这几乎就像 Math.min 应该是 Math.max ???

在我当前的项目中,我想在 30 秒后连接失败,这在当前设置中是不可能的。

我正在使用 4.1 postgres jdbc 驱动程序,但我认为这与上述问题无关。

非常感谢 - 很酷的池库!!!

4

1 回答 1

5

好的,这里有几个活动部分。首先,Math.min()是bug,应该是Math.max()。鉴于此(它将被修复),请考虑以下事项:

需要注意的是,连接是在池中异步创建的。setConnectionTimeout()设置调用getConnection()超时前等待连接的最长时间(以毫秒为单位)。

DataSourceloginTimeout是在超时之前启动到数据库的物理连接的最长时间。因为 HikariCP 是异步获取连接的,如果连接尝试失败,HikariCP 会继续重试,但你的调用getConnection()会适当超时。我们正在使用 connectionTimeout 的双重职责loginTimeout

例如,假设池完全是空的,并且您已将 a 配置connectionTimeout为 30 秒。当您调用getConnection()HikariCP 时,意识到没有可用的空闲连接,开始尝试获取一个新连接。loginTimeout在这种情况下,超过 30 秒没有什么意义。

调用的目的Math.max()是确保如果用户已配置为,我们永远不会设置loginTimeout为。 没有. _ 如果用户配置了 a of ,意味着他们永远不想超时,则时间转换会导致几千年的超时(几乎从不)。0connectionTimeout250msTimeUnit.MILLESECONDS.toSeconds()0Math.max()connectionTimeout0Integer.MAX_VALUE

话虽如此,鉴于 HikariCP 与数据库的连接是如何异步获取的,即使没有Math.max()修复,您也应该能够实现 30 秒的应用程序级连接超时。除非与数据库的物理连接超过 1000 毫秒,否则您不会受到Math.min().

我们将在接下来的几个小时内发布 2.2.5-rc3 候选版本。我将插入此修复程序。

于 2014-11-12T10:14:11.340 回答