连接池问题

时间:2013-06-11 14:37:29

标签: java mysql spring hibernate connection-pooling

如果我在闲置一段时间后启动我的应用程序,我以前会遇到错误。 (我使用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"/>

我问过这个问题here,这个问题对解决方案更具体。我需要知道为什么我会收到这个错误。

我尝试了上述link中提供的第1个(使用autoReconnect = true配置连接字符串)和第3个选项(配置连接池以测试连接的有效性),并且两个都有效。我仍然不明白为什么在第一时间我得到了错误。

这是我更新的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>

是否有连接到期问题?请帮我理解。

1 个答案:

答案 0 :(得分:8)

以下是用于说明正在发生的事件的事件流程:

  1. 呼叫者(应用程序或连接池)请求并使用连接
  2. 调用者保留对它的引用,以便可以重用连接
  3. 来电者经历一段时间不活动(例如,一夜之间开发系统或周末的QA系统)。
  4. 数据库连接未使用后,数据库会认为连接处于空闲状态。因为它是空闲的,在一段时间后(MySQL默认为8小时),数据库将关闭连接。
  5. 调用者仍然有连接句柄,当调用者再次尝试使用连接时,会不愉快地发现连接已关闭。
  6. autoReconnect = true的原因是什么,以及测试连接有效性的池是否正常,是指示调用系统测试此情况的连接,如果发生这种情况则再次尝试。

    验证查询是否会影响性能:理论上它是使用连接来做某事。在实践中,某些东西是如此微不足道,以至于在整个系统的背景下它的影响可以忽略不计。

    [编辑]

    在这种情况下,Apache DBCP是挂在连接上的连接池,但是您不希望DBCP在每次调用后关闭连接。连接池的目的是为下次调用保持连接,因为创建连接很昂贵。池维护的连接对象由实际数据库连接支持,数据库是在空闲超时期限后关闭该实际连接的数据库。请注意,关闭空闲连接的超时是在数据库上配置的,而不是在连接池上配置的。因此,DBCP无法知道连接是否已关闭,除非它实际上尝试连接它。这就是您需要验证查询的原因。

    有关配置DBCP的详细信息,请参阅configuration pageAPI docs