【问题标题】:Hibernate, c3p0, and Mysql, springHibernate、c3p0 和 Mysql、spring
【发布时间】:2013-03-06 15:35:28
【问题描述】:

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

我在我的应用程序中使用 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();
        } 

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

--Om--

【问题讨论】:

    标签: mysql hibernate spring-mvc c3p0


    【解决方案1】:
    Caused by: CommunicationsException: Communications link failure
    

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

    既然你能够连接到数据库,我猜问题可能是

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

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

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

    【讨论】:

      【解决方案2】:

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

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

      ==> 说了这么多,不清楚你的“Connection”类在这里是什么。看起来它毕竟不是 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) 短得多。

      祝你好运!

      【讨论】:

      • 非常感谢 Steve 我的 Connection 类快照就像公共类 Connection { static EntityManagerFactory emf;公共静态EntityManager em;静态实体交易 t;公共连接(){ emf =Persistence.createEntityManagerFactory(“RollerSkattePU”); em = emf.createEntityManager();我改变了我的代码。很快就会分享我的问题解决了吗?
      【解决方案3】:

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

      这是一个令人讨厌的错误的原因是应用程序将通过省略:

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

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

      【讨论】:

        【解决方案4】:

        您应该为您配置一个数据源。不然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>
        

        【讨论】:

          猜你喜欢
          • 2012-06-30
          • 2010-10-18
          • 1970-01-01
          • 1970-01-01
          • 2011-02-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-06-26
          相关资源
          最近更新 更多