一尘不染

连接池问题

hibernate

如果我在闲置了一段时间后启动应用程序,那么我曾经遇到以下错误。(我正在使用Spring + Hibernate + MySQL作为DB)

ERROR [org.hibernate.util.JDBCExceptionReporter]The last packet successfully received from the server was 74,188,684 milliseconds ago. 
The last packet sent successfully to the server was 74,188,685 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.
org.hibernate.exception.JDBCConnectionException: could not execute query

我通过将以下内容添加到我的servlet-context.xml中解决了这个问题。

<beans:property name="validationQuery" value="SELECT 1"/>

我在这里问了这个问题,这个问题是解决方案所特有的。我需要知道为什么会遇到这个错误。

我尝试了上面链接中提供的第一个选项(使用autoReconnect =
true配置连接字符串)和第三个选项(配置连接池以测试连接的有效性),并且都可以使用。仍然我不明白为什么我首先遇到错误。

这是我更新的servlet-context.xml文件,我正在使用ApacheDBCP进行连接池。

<beans:bean id="MyID" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <beans:property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <beans:property name="url" value="jdbc:mysql://localhost:17761/myDB"/>
        <beans:property name="username" value="myname"/>
        <beans:property name="password" value="mypwd"/>
        <beans:property name="maxIdle" value="5"/>
        <beans:property name="maxActive" value="20"/>
        <beans:property name="minIdle" value="5"/>
        <beans:property name="validationQuery" value="SELECT 1"/>
</beans:bean>

是连接到期问题吗?请帮助我理解。


阅读 250

收藏
2020-06-20

共1个答案

一尘不染

这是事件流,以说明正在发生的事情:

  1. 调用方(应用程序或连接池)请求并使用连接
  2. 调用方保留对其的引用,以便可以重新使用该连接
  3. 呼叫者会经历一段闲置时间(例如,一整夜的dev系统或一周末的QA系统)。
  4. 一旦不使用该数据库连接,数据库就会认为该连接处于空闲状态。由于它是空闲的,因此在一定时间(MySQL默认值为8小时)后,数据库将关闭连接。
  5. 调用方仍然具有该连接的句柄,并且当调用方再次尝试使用该连接时,它不愉快地发现该连接已关闭。

autoReconnect =
true起作用的原因以及测试连接有效性的池起作用的原因是,您正在指示调用系统针对这种情况测试连接,并在这种情况发生时再次尝试。

至于验证查询是否会影响性能:从理论上讲,它是使用连接来做某事。在实践中,某些事情是如此琐碎,以至于在整个系统的环境中其影响可以忽略不计。

[编辑]

在这种情况下,Apache
DBCP是挂在连接上的连接池,但是您不希望DBCP在每次调用后关闭连接。连接池的重点是使连接为下一次调用做好准备,因为创建连接非常昂贵。池维护的连接对象由实际的数据库连接支持,而数据库是在空闲超时时间后关闭该实际连接的数据库。请注意,关闭空闲连接的超时是在数据库上配置的,而不是在连接池上配置的。因此,除非DBCP实际上尝试与其连接,否则DBCP无法知道该连接是否已关闭。这就是为什么您需要验证查询的原因。

有关配置DBCP的更多信息,请参见配置页面API文档

2020-06-20