只是寻找对这段代码的理由的解释(PoolUtiltites:版本2.2.4中的293):
dataSource.setLoginTimeout((int) TimeUnit.MILLISECONDS.toSeconds(Math.min(1000L, connectionTimeout)));
此代码和setConnectionTimeout方法意味着我得到了这种行为:
这对我来说真的很奇怪!
这几乎就像Math.min应该是Math.max ???
在我目前的项目中,我想在30秒后失败,这在目前的设置中是不可能的。
我正在使用4.1 postgres jdbc驱动程序,但我认为这与上述问题无关。
非常感谢 - 和酷池图书馆!!!
答案 0 :(得分:3)
好的,这里有几个活动部件。首先,Math.min()
是一个错误,它应该是Math.max()
。鉴于此(将被修复)考虑以下因素:
请务必注意,池中异步创建 连接。 setConnectionTimeout()
设置在超时之前调用getConnection()
将等待连接的最长时间(以毫秒为单位)。
DataSource loginTimeout
是在超时之前启动到数据库的物理连接的最长时间。由于HikariCP异步获取连接,如果连接尝试失败,HikariCP将继续重试,但您对getConnection()
的调用将适当地超时。我们使用connectionTimeout作为loginTimeout
的双重任务。
例如,假设池完全为空,并且您已配置了30秒的connectionTimeout
。当您致电getConnection()
HikariCP时,意识到没有空闲连接可用,请开始尝试获取新连接。在这种情况下,loginTimeout
超过30秒是没有意义的。
Math.max()
调用的目的是确保如果用户已将loginTimeout
配置为0
,我们永远不会将connectionTimeout
设置为250ms
。没有TimeUnit.MILLESECONDS.toSeconds()
,0
会返回Math.max()
。如果用户配置了connectionTimeout
0
,意味着他们永远不想超时,那么Integer.MAX_VALUE
的时间转换会导致数千年超时(虚拟从不)。
话虽如此,并且鉴于HikariCP与数据库的连接是如何异步获得的,即使没有Math.max()
修复,您也应该能够实现30秒的应用程序级连接超时。除非与数据库的物理连接超过1000毫秒,否则您将不受Math.min()
的影响。
我们将在接下来的几个小时内推出一个2.2.5-rc3的候选版本。我将插入此修复程序。