【问题标题】:Hibernate/mysql connection issues休眠/mysql 连接问题
【发布时间】:2012-10-29 03:52:50
【问题描述】:

我们正在开发一个带有 Hibernate 3 ORM 的 java struts2 框架 web 应用程序。我们使用 mysql 作为我们的数据库。

我们在日志中发现了一些与数据库相关的异常。与数据库的连接在配置的时间之前超时。以下是我们发现的公共异常。

104343235 [pool-6-thread-19] ERROR org.hibernate.util.JDBCExceptionReporter  - The last packet successfully received from the server was 100,838,460 milliseconds ago.  The last packet sent successfully to the server was 100,838,461 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
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:99)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
    at org.hibernate.loader.Loader.doList(Loader.java:2536)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2276)
    at org.hibernate.loader.Loader.list(Loader.java:2271)
    at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:452)
    at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:363)
    at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:196)
    at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1268)
    at org.hibernate.impl.QueryImpl.list(QueryImpl.java:102)
    at com.myproject.model.dao.entities.EntitiesDAO.getByIds(EntitiesDAO.java:148)

Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 100,838,460 milliseconds ago.  The last packet sent successfully to the server was 100,838,461 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.
    at sun.reflect.GeneratedConstructorAccessor345.newInstance(Unknown Source)104343242 [pool-6-thread-16] ERROR org.hibernate.util.JDBCExceptionReporter  - The last packet successfully received from the server was 100,838,544 milliseconds ago.  The last packet sent successfully to the server was 100,838,544 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.
104343242 [pool-6-thread-16] ERROR org.hibernate.util.JDBCExceptionReporter  - The last packet successfully received from the server was 100,838,544 milliseconds ago.  The last packet sent successfully to the server was 100,838,544 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.

at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
    at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1117)
    at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3829)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2449)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2629)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2719)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)
    at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2318)
    at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewProxyPreparedStatement.java:76)
    at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208)
    at org.hibernate.loader.Loader.getResultSet(Loader.java:1953)
    at org.hibernate.loader.Loader.doQuery(Loader.java:802)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)
    at org.hibernate.loader.Loader.doList(Loader.java:2533)
    ... 21 more

每天我们都会重新启动我们的应用服务器,作为对问题的临时修复。

我们将不胜感激。

【问题讨论】:

标签: java mysql hibernate


【解决方案1】:

发生这种情况是因为 MySQL 服务器在超时后终止了没有任何活动的连接。 您需要在 dbcp 配置中添加几行 尝试添加以下参数:

validationQuery="SELECT 1"
testOnBorrow="true

工作原理:连接池在返回连接之前尝试运行validationQuery。如果validationQuesry 失败,dbcp 会丢弃连接,创建一个新连接并将其返回。

这是一个例子:

<Resource   name="jdbc/cooldatabase"
            description="Strandls.com license database"
            auth="Container"
            type="javax.sql.DataSource"
            factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"
            driverClassName="com.mysql.jdbc.Driver"
            url="jdbc:mysql://localhost:3306/cooldatabase?autoReconnect=true"
            username="cooluser"
            password="coolpassword"
            initialSize="0"
            maxActive="20"
            maxIdle="10"
            minIdle="0"
            maxWait="-1"
            validationQuery="SELECT 1"
            testOnBorrow="true"
            poolPreparedStatements="true"
            removeAbandoned="true"
            removeAbandonedTimeout="60"
            logAbandoned="true"/>

您可以在这里找到完整的详细信息:http://amitcodes.wordpress.com/2008/07/26/16/

【讨论】:

  • 如何为 c3p0 连接池实现相同的功能?
  • 到目前为止我从未使用过 c3p0,但根据讨论,有一个名为 testConnectionOnCheckout 的属性:&lt;property name="testConnectionOnCheckout"&gt;true&lt;/property&gt;Here 是完整的讨论:forum.hibernate.org/viewtopic.php?f=1&t=1015229
  • Source : community.jboss.org/wiki/… testConnectionOnCheckout 必须在c3p0.properties中设置,默认值为false。不要使用它,这个功能非常昂贵。如果设置为 true,将在每次连接检查时执行操作以验证连接是否有效。更好的选择是使用c3p0.idleConnectionTestPeriod 定期验证连接。
  • 我们正在使用 - 300 这是你提到的那个还是另一个?
  • 我的错,c3p0.idle_test_period 是覆盖 c3p0.idleConnectionTestPeriod 的休眠配置键。
【解决方案2】:

在 Hibernate 中使用连接池。例如c3p0https://community.jboss.org/wiki/HowToConfigureTheC3P0ConnectionPool

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-24
    • 2016-06-16
    • 2014-08-08
    • 2013-04-20
    • 2017-09-25
    • 2020-03-02
    • 1970-01-01
    相关资源
    最近更新 更多