由于各种原因,池中的连接可能变为无效:服务器连接超时,网络问题......
我的理解是Tomcat JDBC连接池不保证它为应用程序提供的连接的有效性。
为了防止(实际上只降低风险)从池中获得无效连接,解决方案似乎是连接验证的配置。验证连接意味着在数据库上运行非常基本的查询(例如MySQL上的SELECT 1;
)。
Tomcat JDBC连接池提供了几个测试连接的选项。我发现更有趣的两个是testOnBorrow
和testWhileIdle
。
首先我认为testOnBorrow
是最好的选择,因为它在将它提供给应用程序之前基本上验证了连接(最大频率由validationInterval
定义)。
但是经过一秒钟后我才意识到在使用它之前测试连接可能会影响应用程序的响应能力。所以我虽然使用testWhileIdle
可以更高效,因为它在不使用时测试连接。
无论我选择哪个选项,它们似乎只会降低获得无效连接的风险,但这种风险仍然存在。
所以我最后问:我应该使用testOnBorrow
或testWhileIdle
还是两者兼而有之?
在旁注,我很惊讶validationInterval
不适用于testOnReturn
而且我真的没有达到testOnConnect
的目的。
这没有100%正确的答案。这是一个权衡和背景的问题。
如果你有一个繁忙的应用程序,具有非常好的数据库连接可靠性,那么你将从数据开始看到,“对来自池的每个连接请求的有效性检查”的成本超过检测连接问题的好处。
最后一个数据点是,对于某些应用程序,关键路径不是“验证查询”时间(希望以较低的毫秒数)。应用程序有更大的问题需要处理。当然,对于某些应用来说,那个时间非常重要。
只是为了让你知道,我刚刚对此进行了测试,可以同时使用testOnBorrow
和testOnIdle
属性。
然而,如上所述,我将选择testOnBorrow
,因为我的应用程序没有大量流量,并且能够在握住它之前验证连接。
正如评论中指出的那样,testOnBorrow
不需要验证查询。如果你确实选择保留一个它可以是一个简单的选择:
jdbc.hive.testOnBorrow=true
jdbc.hive.validationQuery=SELECT 1
如果您想使用testWhileIdle
,您可以使用以下内容:
jdbc.testWhileIdle=true
jdbc.minEvictableIdleTimeMillis=1800000
jdbc.timeBetweenEvictionRunsMillis=1800000`
有关DBCP的更多信息:https://commons.apache.org/proper/commons-dbcp/configuration.html