2

堆栈溢出时存在许多相关问题,但我仍然提出这个问题,因为我仍然没有明确的解决方案和我的问题的确切原因。我希望在这里我能完全解决我的问题并为所有人提供帮助

我在我的应用程序中使用 c3p0、MySQL、hibernate(J PA) 和 spring。我在我的应用程序中使用的主要 jar 文件列表是:

c3p0-0.9.2.jar
mchange-commons-java-0.2.3.3.jar
hibernate-commons-annotations-3.0.0.ga.jar
hibernate-entity manager.jar
hibernate-tools.jar
hibernate-validator-4.0.2.GA.jar
hibernate3.jar
mysql-connector-java-5.1.13-bin.jar

我的 persistent.XML 中的 c3p0 设置是这样的:

<property name="hibernate.c3p0.timeout" value="300"/>
<property name="hibernate.c3p0.max_statements" value="50"/>
<property name="hibernate.c3p0.idle_test_period" value="300"/>

在这里,我读到 hibernate.c3p0.idle_test_period 不能高于 hibernate.c3p0.timeout。就我而言,两者都是平等的。

我需要改变什么吗?我怎么解决这个问题 ?

服务器可以正常工作几个小时(可能不完全是 8 小时)并给出以下错误。错误日志是:

    Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: 
    Communications link failure
    The last packet successfully received from the server was 35,019,246 milliseconds
     ago.  The last packet sent successfully to the server was 0 milliseconds ago.
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at             sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
        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:409)
        at         com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1118)
        at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3055)
        at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2941)
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3489)
        at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1959)
        at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2113)
        at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2568)
        at         com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2113)
        at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2275)
        at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery
    (NewProxyPreparedStatement.java:116)
        at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:186)
        at org.hibernate.loader.Loader.getResultSet(Loader.java:1787)
        at org.hibernate.loader.Loader.doQuery(Loader.java:674)
        at  org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
        at org.hibernate.loader.Loader.doList(Loader.java:2220)
        ... 39 more
    Caused by: java.io.EOFException: Can not read response from server.
    Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.
        at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:2502)
        at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2952)
        ... 52 more
    ... 39 more
    Caused by: java.net.SocketException: Broken pipe
        at java.net.SocketOutputStream.socketWrite0(Native Method)
        at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:109)
        at java.net.SocketOutputStream.write(SocketOutputStream.java:153)
        at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
        at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
        at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3302)
        ... 50 more

在这里,我展示了我的 persistent.xml 的快照:-

<properties>
      <property name="hibernate.connection.username" value="****"/>
      <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
      <property name="hibernate.connection.password" value="***************"/>
      <property name="hibernate.connection.url" value="jdbc:mysql://xxx.xxx.x.xx:3306/projectname?autoReconnect=true"/>
      <!--Connection Pooling c3p0 configuration-->
      <!--Minimum number of JDBC connections in the pool. Hibernate default: 1-->
      <property name="hibernate.c3p0.min_size" value="5"/>
      <!--Maximum number of JDBC connections in the pool. Hibernate default: 100-->
      <property name="hibernate.c3p0.max_size" value="20"/>
      <!--When an idle connection is removed from the pool (in second). Hibernate default: 0, never expire.-->
      <property name="hibernate.c3p0.timeout" value="300"/>
      <!--Number of prepared statements will be cached. Increase performance. Hibernate default: 0 , caching is disable.-->
      <property name="hibernate.c3p0.max_statements" value="50"/>
      <!--idle time in seconds before a connection is automatically validated. Hibernate default: 0-->
      <property name="hibernate.c3p0.idle_test_period" value="300"/>
    </properties>

我在我的应用程序中使用连接类的单例对象。

public static void createConnection() 
{
    if (em != null) 
       {
            Connection.em.clear();
        }
        if (em == null) {
            new Connection();
        } 

提前致谢。希望我能得到我的解决方案。

--嗡--

4

4 回答 4

2

单例 Connection 对象是一个坏主意(至少它在任何并发的多客户端应用程序中)。它肯定与连接池不一致,其理念是在需要连接时应从池中获取连接,并在完成一个工作单元后立即返回到池中[通过调用 close()]。

现在,您的单例连接将超时,c3p0 对此无能为力。连接池在将连接签入池时对其进行管理和测试。当他们被签出时,游泳池会尽量不碍事,不干扰客户。

==> 说了这么多,目前还不清楚您的“连接”类在这里是什么。看起来它毕竟不是 java.sql.Connection,因为在 Connection 中有一个名为“em”的静态字段。所以很难解释发生了什么。

从广义上讲,您需要一个 c3p0 数据源,并根据需要获取连接并尽快关闭()它们。

为了防止像您看到的连接超时,最好的方法是连接测试制度。最简单的方法是设置...

hibernate.c3p0.validate=true
hibernate.c3p0.preferredTestQuery=SELECT 1

一旦你有这个工作,你可以通过使用 testConnectionOnCheckin 和 idleConnectionTestPeriod(或 hibernate.c3p0.idle_test_period)来稍微提高性能。见http://www.mchange.com/projects/c3p0/#configuring_connection_testing

让您的 idleConnectionTestPeriod (hibernate.c3p0.idle_test_period) 和 maxIdleTime (hibernate.c3p0.timeout) 相同是没有意义的。永远不会测试空闲连接;他们将在获得机会之前到期。idleConnectionTestPeriod (hibernate.c3p0.idle_test_period),如果你设置它,应该比 maxIdleTime (hibernate.c3p0.timeout) 短得多。

祝你好运!

于 2013-03-18T11:13:03.090 回答
1

由于这是 Google 的第一个热门,我将分享是什么让我解决了在我们的生产服务器上出现的这个问题:http: //drglennn.blogspot.nl/2009/05/javasqlsqlexception-communication-link.html

使这是一个令人讨厌的错误的原因是应用程序将通过省略以下内容来工作:

 <property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property> 

在您的持久性单元配置中,但它不会使用 C3P0 连接池,因此会产生连接失败。

于 2013-04-18T12:05:21.660 回答
0
Caused by: CommunicationsException: Communications link failure

该异常意味着无法访问数据库。

由于您能够连接到数据库,我猜问题可能是

1)当时数据库服务器已关闭

2) 数据库服务器已用完连接。

在遇到此异常时,尝试使用其他工具、MySQL Workbench 或从控制台连接到数据库

于 2013-03-18T10:33:38.920 回答
0

您应该为您配置一个数据源。不然spring an c3o0的交互有很多麻烦。

<bean id="dataSource_core" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass" value="${hibernate.connection.driver_class}" />
    <property name="jdbcUrl" value="${hibernate.connection.url}" />
    <property name="user" value="${hibernate.connection.username}" />
    <property name="password" value="${hibernate.connection.password}" />
    <property name="minPoolSize" value="${hibernate.connection.minPoolSize}" />
    <property name="maxPoolSize" value="${hibernate.connection.maxPoolSize}" />
    <property name="maxIdleTime" value="${hibernate.connection.maxIdleTime}" />
    <property name="maxStatements" value="${hibernate.connection.maxStmts}" />
    <property name="testConnectionOnCheckout" value="${hibernate.connection.testCo}" />
    <property name="testConnectionOnCheckin" value="${hibernate.connection.testCo}" />
    <property name="preferredTestQuery" value="${hibernate.connection.testSQL}" />
    <property name="idleConnectionTestPeriod" value="${hibernate.connection.testPeriod}" />
</bean>
于 2014-10-16T16:16:32.730 回答