我在我的 Web 应用程序(没有 Spring)中结合使用 Hibernate 和 c3p0。一夜之间,我的数据库连接似乎超时(或至少其中一个),第二天我得到了一个损坏的管道异常。
以下是我用于该项目的配置。
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/**********?autoReconnect=true</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
<property name="hibernate.connection.username">********</property>
<property name="hibernate.connection.password">********</property>
<property name="hibernate.show_sql">false</property>
<property name="hibernate.globally_quoted_identifiers">true</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
<property name="hibernate.connection.autocommit">false</property>
<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">25</property>
<property name="hibernate.c3p0.timeout">300</property>
<property name="hibernate.c3p0.max_statements">50</property>
<property name="hibernate.c3p0.idle_test_period">60</property>
<property name="hibernate.c3p0.acquire_increment">1</property>
<property name="hibernate.c3p0.acquireRetryAttempts">5</property>
<property name="hibernate.c3p0.acquireRetryDelay">250</property>
<property name="hibernate.c3p0.preferredTestQuery">select 1;</property>
<property name="hibernate.c3p0.validate">true</property>
<property name="hibernate.c3p0.testConnectionOnCheckout">true</property>
<property name="hibernate.c3p0.testConnectionOnCheckin">true</property>
</session-factory>
</hibernate-configuration>
我得到的异常如下所示:
从服务器成功接收到的最后一个数据包是 56,974,967 毫秒前。 最后一个成功发送到服务器的数据包是 56,974,967 毫秒前。是 长于服务器配置的“wait_timeout”值。你应该考虑 在您的应用程序中使用之前过期和/或测试连接有效性,增加 服务器为客户端超时配置值,或使用连接器/J 连接 属性 'autoReconnect=true' 来避免这个问题。 org.hibernate.exception.JDBCConnectionException:最后一个数据包成功接收 来自服务器的时间是 56,974,967 毫秒前。最后一个数据包成功发送到 服务器在 56,974,967 毫秒前。比服务器配置的值长 'wait_timeout'。您应该考虑过期和/或测试连接 在您的应用程序中使用之前的有效性,增加服务器配置的值 客户端超时,或使用 Connector/J 连接属性 'autoReconnect=true' 避免这个问题。
这里的问题是,我正在使用属性 autoReconnect=true,并且我正在测试连接有效性。(请参阅 c3p0 配置。)我相当确定 c3p0 配置已加载,因为以下内容显示在我的标准输出日志中:
2014 年 4 月 8 日上午 10:57:13 com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource getPoolManager 信息:初始化 c3p0 池... com.mchange.v2.c3p0.PoolBackedDataSource@f79fb235 [ connectionPoolDataSource -> com.mchange.v2.c3p0.WrapperConnectionPoolDataSource@4e20d034 [ acquireIncrement -> 1,acquireRetryAttempts -> 5,acquireRetryDelay -> 250,autoCommitOnClose -> 假,自动测试表 -> 空,breakAfterAcquireFailure -> 假,checkoutTimeout -> 0, connectionCustomizerClassName -> null,connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester,debugUnreturnedConnectionStackTraces -> false, factoryClassLocation -> null,forceIgnoreUnresolvedTransactions -> false,identityToken -> ph9ube91hyyxjw1mgbhpo|709689fb,idleConnectionTestPeriod -> 60,initialPoolSize -> 3, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 300, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 25, maxStatements -> 50, maxStatementsPerConnection -> 0,minPoolSize -> 5,nestedDataSource -> com.mchange.v2.c3p0.DriverManagerDataSource@a1ca3a3 [ 描述 -> null,driverClass -> null, factoryClassLocation -> null,identityToken -> ph9ube91hyyxjw1mgbhpo|24bbab7, jdbcUrl -> jdbc:mysql://localhost:3306/********?autoReconnect=true, 属性 -> {user=******, password=******, autocommit=false} ], preferredTestQuery -> 选择 1;, propertyCycle -> 0, testConnectionOnCheckin -> true, testConnectionOnCheckout -> true, unreturnedConnectionTimeout -> 0,使用TraditionalReflectiveProxies -> false;用户覆盖:{}], dataSourceName -> null, factoryClassLocation -> null, identityToken -> ph9ube91hyyxjw1mgbhpo|fedb05d, numHelperThreads -> 3]
异常的损坏管道部分是这样的:
引起:com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:从服务器成功接收到的最后一个数据包是 56,974,967 毫秒前。最后一个成功发送到服务器的数据包是 56,974,967 毫秒前。比服务器配置的“wait_timeout”值长。您应该考虑在应用程序中使用之前使连接有效性过期和/或测试,增加客户端超时的服务器配置值,或使用连接器/J 连接属性“autoReconnect=true”来避免此问题。 在 sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 在 sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) 在 sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 在 java.lang.reflect.Constructor.newInstance(Constructor.java:525) 在 com.mysql.jdbc.Util.handleNewInstance(Util.java:411) 在 com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1116) 在 com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3851) 在 com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2471) 在 com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2651) 在 com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2683) 在 com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2144) 在 com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2310) 在 com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewProxyPreparedStatement.java:76) 在 sun.reflect.GeneratedMethodAccessor35.invoke(未知来源) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.lang.reflect.Method.invoke(Method.java:601) 在 org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:122) ... 23 更多 引起:java.net.SocketException: Broken pipe 在 java.net.SocketOutputStream.socketWrite0(本机方法) 在 java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:109) 在 java.net.SocketOutputStream.write(SocketOutputStream.java:153) 在 java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82) 在 java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140) 在 com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3832) ... 33 更多
根据我在互联网上找到的内容,我尝试了以下方法:
- 将 autoReconnect=true 添加到连接 URL (请注意,尝试使用后连接仍然断开,因此似乎没有重新连接)
- 将 testConnectionOnCheckout 和 testConnectionOnCheckin 添加到 c3p0 配置中
- 将 idle_test_period 和 preferredTestQuery 添加到 c3p0 配置
似乎没有任何效果。有没有人知道可能导致此问题的原因?