MySQLNonTransientConnectionException / jdbc4.CommunicationsException错误使用C3P0时继续

时间:2015-05-20 17:25:55

标签: mysql hibernate jdbc c3p0

我正在使用Hibernate和C3P0作为连接池,MySQL 5.6数据库运行Java Web应用程序。我继续遇到连接超时并产生错误的已部署应用程序的问题:

  

引起:com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:最后一个数据包成功   从服务器收到的是426,126,080毫秒之前。最后一个数据包成功发送到   该服务器是426,126,081毫秒前。比服务器配置的值长   'WAIT_TIMEOUT'。您应该考虑之前过期和/或测试连接有效性   在您的应用程序中使用,增加服务器配置的客户端超时值或使用   Connector / J连接属性'autoReconnect = true'以避免此问题。

特别是,任何不活动期都会导致错误开始。很长一段时间都会导致以下错误:

  

(DefaultConnectionTester.java:148)[http-nio-8080-exec-9]:Exception测试的SQL状态'08007'   by statusOnException()意味着数据库无效,池应该重新填充   与新鲜的连接。 com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:   commit()期间通信链路失败。交易决议未知。

  

(C3P0PooledConnectionPool.java:981)[http-nio-8080-exec-9]:ConnectionTest失败,   报告所有先前获得的连接可能无效。该池将被重置。

Hibernate / C3P0连接参数是:

<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<property name="hibernate.c3p0.initial_pool_size">5</property>
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">50</property>
<property name="hibernate.c3p0.acquire_increment">5</property>
<property name="hibernate.c3p0.max_statements">500</property>
<property name="hibernate.c3p0.timeout">1800</property> <!-- in secs -->
<property name="hibernate.c3p0.idle_test_period">480</property> <!-- in secs -->
<property name="hibernate.c3p0.testConnectionOnCheckout">false</property>
<property name="hibernate.c3p0.testConnectionOnCheckin">true</property>
<property name="hibernate.c3p0.preferredTestQuery">select 1</property>
<property name="hibernate.c3p0.maxConnectionAge">3600</property> <!-- in secs -->
<property name="hibernate.c3p0.numHelperThreads">8</property>
<property name="hibernate.c3p0.maxIdleTimeExcessConnections">600</property>

我已经多次尝试根据有关此主题和C3P0文档的其他评论来调整C3P0参数,但无济于事。 Web应用程序经历了不活动和大量使用的时期,当然必须有一些关于如何在此用例中配置连接池的指导,但我还没有找到任何可以解决此问题的方法。

1 个答案:

答案 0 :(得分:0)

我认为您需要将testConnectionOnCheckout的值更改为:

<property name="hibernate.c3p0.testConnectionOnCheckout">true</property>

想象一下这种情况(使用您当前的配置):

  • 您刚刚过期的池中有一个连接
  • 每隔480秒检查空闲连接的线程还没有启动
  • 用户访问网站...从池中获取连接,第一次尝试使用时会出现异常,因为它已过期且C3P0未在结帐时测试连接

必须做的另一件事是检查mysql中配置的超时。如果超时配置为60秒,并且您每480秒检查一次连接...那么您的所有连接肯定会被关闭。作为一个好的经验法则,空闲测试周期应该是DB中配置的超时的1/2到3/4,以确保连接保持打开状态。

您还需要考虑中间的防火墙,因为如果他们看不到流量,他们可能会更快地关闭连接。