【问题标题】:Connection pool issue连接池问题
【发布时间】:2013-06-11 14:37:28
【问题描述】:

如果我在空闲一段时间后启动我的应用程序,我会遇到以下错误。 (我使用 Spring+Hibernate+MySQL 作为数据库)

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 中提供的第一个(使用 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>

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

【问题讨论】:

    标签: java mysql spring hibernate connection-pooling


    【解决方案1】:

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

    1. 调用者(应用程序或连接池)请求并使用了一个连接
    2. 调用者保留对它的引用,以便可以重新使用连接
    3. 调用者经历了一段时间的不活动(例如,开发系统通宵工作或 QA 系统通宵工作)。
    4. 一旦未使用该数据库连接,数据库就会认为该连接处于空闲状态。因为它是空闲的,在一定时间后(MySQL 默认是 8 小时)数据库关闭连接。
    5. 调用者仍有连接的句柄,当调用者再次尝试使用该连接时,却发现该连接已关闭。

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

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

    [编辑]

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

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

    【讨论】:

    • 完美的杰,非常感谢,现在我的下一个问题,工作完成后如何处理呼叫者断开连接?
    • 如果它使用连接运行实际查询会不会更好,如果它失败然后使连接过期?这样我们就不必每次都运行validationQuery。
    猜你喜欢
    • 2011-04-01
    • 2012-09-25
    • 2011-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-24
    相关资源
    最近更新 更多