连接池 - 为什么要在签入时测试连接?

时间:2016-06-16 04:50:29

标签: java hibernate connection-pooling c3p0

你好这个问题应该适用于比c3p0更多的连接池管理器,但我会使用那个例子。

连接池管理的一个选项c3p0是在连接被检入连接池之前测试连接。 这是否意味着在应用程序使用连接后?如果是这样,如果连接仅由应用程序使用,那么连接是否始终有效?

除非我的理解是错误的,否则这似乎是一个无用的时间来检查连接是否有效,因为当应用程序尝试使用它时,无效连接会引发异常。

更新 我问的真正问题是,在应用程序中失败的陈旧连接是否仍会被重新检入池中以最终一次又一次失败?如果答案是否定的,那么在办理登机手续时进行测试将是毫无意义的,因为爆炸了#39;连接永远不会被发送回池。我一直在使用c3p0和testOnCheckIn以及多年的测试查询间隔而没有实际深入了解原因。

2 个答案:

答案 0 :(得分:2)

在结账时测试连接是否是一个性能问题在很大程度上取决于测试的效率,以及Connection在签出时的工作量。正如您所说,配置连接测试最安全,最简单的方法是在结账时进行测试。但这也意味着客户必须经历测试的延迟。

如果希望异步测试Connections,即 客户端代码路径之外的,则需要在签入时测试Connections,并在签入Connections时定期测试。基本上,策略是为了确保池中空闲的连接不太可能无效,以便您可以安全地检查它们而无需进行测试。 (“安全”当然是程度问题。即使在结账时测试,连接也会在测试和第一次客户端使用之间失效。)

假设Connection在登记时有效是不好的,因为客户刚刚使用过它。首先,客户端遇到异常这一事实并不一定向池发信号通知Connection无效。例如,对Connection.commit()的调用可能会因为事务中行的并发修改而失败,即使Connection完全有效。从根本上说,在签出连接时遇到的例外是客户的业务,而不是池的业务。 c3p0(我认为异常)会注意到客户端遇到的异常,并触发静默连接测试,以便池可以推断连接有效性。但是有很多原因导致客户端可能会遇到有效连接中的异常。

其次,在客户端最后使用后,池不能依赖于Connection的快速签入。这是一个坏主意,但客户端通常将Connections打开的时间比实际的数据库工作长得多。在las客户端使用和签到之间的任何时间窗口显然都是一个连接可能变坏的窗口。

所以,如果你想进行异步连接测试 - 即连接测试(对于足够大的池)没有对客户端延迟做出贡献 - 你需要一个check-on-checkin然后频繁测试,同时连接被合并并空闲

所有这些都说,实际上,异步连接测试的需求已经减少,因为JDBC驱动程序现在通过Connection.isValid()提供快速,可靠的测试。曾几何时,为了定义DBMS独立,可靠的连接测试,c3p0必须默认为针对数据库元数据的常常非常慢的查询。此测试的延迟可能会严重影响客户端性能。使用Connection.isValid()(或高效的preferredTestQuery),测试通常足够快,以便结帐测试的简单性和稳健性超过小客户端延迟命中。 c3p0 docs用于建议出于性能原因使用异步连接测试。 current documentation建议首先进行同步测试检查,如果测试延迟影响性能,则仅退回到异步测试作为潜在优化。在大多数情况下,实际上,您通常最终只使用testConnectionsOnCheckout

答案 1 :(得分:1)

  

这是否意味着应用程序使用连接后?

  

如果是这样,如果应用程序刚刚使用它,那么连接是否始终有效?

如果您的应用使用了该连接,但它似乎已被破坏,那么它会引发异常怎么办?在这种情况下,如果你只是将它放回池中,它将再次返回,另一个请求将失败。经过一段时间后,更多连接可能会中断,请求失败的比例会增加。

有些人在办理登机手续后倾向于测试的原因是他们害怕结账测试的性能影响。您的请求必须等到进行涉及网络流量的SQL查询。这可能会或可能不会对您的应用程序造成真正的危害。

我个人没有进行任何性能测试,也不知道这个问题有多严重,但这也取决于您对应用程序的延迟程度。您也可以依赖@Steve Waldman指出的连接的异步测试 - 这样您就可以在请求处理线程之外测试连接。