【问题标题】:WARN SqlExceptionHelper:143 - SQL Error: 0, SQLState: 08S01- SqlExceptionHelper:144 - Communications link failureWARN SqlExceptionHelper:143 - SQL 错误: 0, SQLState: 08S01- SqlExceptionHelper:144 - 通信链接故障
【发布时间】:2013-03-23 01:43:30
【问题描述】:

我遇到了休眠问题(hibernate-core-4.1.9.Final.jar

案例 1:在 for 循环中进行休眠测试。一切顺利。

for(int i = 0; i < 1500; i++){
    UserDAO.getInstance.getById(1);
}

案例 2:Thread.sleep() 内部循环。 1 分钟后出现异常。

 for(int i=0; i<1500; i++){
     UserDAO.getInstance.getById(1);
     Thread.sleep(60000);
 }

例外:

00:20:06,447  WARN SqlExceptionHelper:143 - SQL Error: 0, SQLState: 08S01
00:20:06,448 ERROR SqlExceptionHelper:144 - Communications link failure

The last packet successfully received from the server was 120,017 milliseconds ago.  The last packet sent successfully to the server was 9 milliseconds ago.
Exception in thread "main" org.hibernate.exception.JDBCConnectionException: Communications link failure

The last packet successfully received from the server was 120,017 milliseconds ago.  The last packet sent successfully to the server was 9 milliseconds ago.
    at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:131)
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110)
    at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:129)
    at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
    at sun.proxy.$Proxy11.executeQuery(Unknown Source)
    at org.hibernate.loader.Loader.getResultSet(Loader.java:2031)
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1832)
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1811)
    at org.hibernate.loader.Loader.doQuery(Loader.java:899)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:341)
    at org.hibernate.loader.Loader.doList(Loader.java:2516)
    at org.hibernate.loader.Loader.doList(Loader.java:2502)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2332)
    at org.hibernate.loader.Loader.list(Loader.java:2327)
    at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:124)
    at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1621)
    at org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:374)
    at org.hibernate.internal.CriteriaImpl.uniqueResult(CriteriaImpl.java:396)
    at com.fit.utilities.BaseDAO.getById(BaseDAO.java:35)
    at com.fit.test.Testiranje.main(Testiranje.java:51)
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet successfully received from the server was 120,017 milliseconds ago.  The last packet sent successfully to the server was 9 milliseconds ago.
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
    at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1121)
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3603)
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3492)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4043)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2503)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2664)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2815)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)
    at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2322)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:122)
    ... 17 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:3052)
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3503)
    ... 29 more

这是我的 hibernate.cfg.xml

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
 
<hibernate-configuration>
 
    <session-factory>

         <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
          <property name="connection.url">jdbc:mysql://xxxxxx:3306/xxxx</property>
          <property name="connection.username">xxxx</property>
          <property name="connection.password">xxxx</property>
          <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
          <property name="hibernate.hbm2ddl.auto">update</property>
          <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
          <property name="show_sql">false</property>
          <property name="hibernate.connection.pool_size">1</property>
        
        <mapping class="com.xxx.model.xxxxx" />
        <mapping class="com.xxx.model.xxxxx" />
        <mapping class="com.xxx.model.xxxxx" />

    </session-factory>
</hibernate-configuration> 

更新: 使用C3P0库解决了这个问题。

 <!-- configuration pool via c3p0--> 
<property name="c3p0.acquire_increment">1</property> 
<property name="c3p0.idle_test_period">100</property> <!-- seconds --> 
<property name="c3p0.max_size">100</property> 
<property name="c3p0.max_statements">0</property> 
<property name="c3p0.min_size">10</property> 
<property name="c3p0.timeout">100</property> <!-- seconds --> 

【问题讨论】:

  • 您找到解决方案了吗?我在生产中遇到类似的错误消息。我无法弄清楚是什么原因造成的,因为系统似乎运行良好
  • 是的,我找到了解决方案..我会发布答案。
  • 我在多线程上下文中也遇到了这个错误。我能够使用 10 个线程更新近 1 个 lac 行,但是当我尝试使用 100 个线程处理另一批 1 个 lac 用户时,我收到了这个错误。我没有在@Transactional 中包装我的休眠代码。

标签: mysql hibernate


【解决方案1】:

由于 MySQL 服务器上 time_out 变量的值较小,因此出现问题。

在我的情况下,time_out 设置为 1 分钟。 使用C3PO池化机制我们可以优化JDBC

下载c3p0 -> http://sourceforge.net/projects/c3p0/

我正在使用 hibernate 3.0

hibernate.cfg.xml

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
 
<hibernate-configuration>
 
    <session-factory>
       
         <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
          <property name="connection.url">jdbc:mysql://databasehost:3306/databasename</property>
          <property name="connection.username">user</property>
          <property name="connection.password">psw</property>
          <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
          <property name="hibernate.hbm2ddl.auto">update</property>
         
          <property name="show_sql">false</property>
         
       <!-- Hibernate c3p0 settings-->
        <property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
        <property name="hibernate.c3p0.acquire_increment">3</property>
        <property name="hibernate.c3p0.idle_test_period">10</property>
        <property name="hibernate.c3p0.min_size">5</property>
        <property name="hibernate.c3p0.max_size">75</property>
        <property name="hibernate.c3p0.max_statements">10</property>
        <property name="hibernate.c3p0.timeout">50</property>
        <property name="hibernate.c3p0.preferredTestQuery">select 1</property>
        <property name="hibernate.c3p0.testConnectionOnCheckout">true</property>
          
         <!-- Mapping files -->
        <mapping class="xxx.xxx.xxx.xxx" />
        <mapping class="xxx.xxx.xxx.xxx" />
        <mapping class="xxx.xxx.xxx.xxx" />
        <mapping class="xxx.xxx.xxx.xxx" />
        
       
    </session-factory>
</hibernate-configuration> 

PersistenceManager.java

import java.io.PrintStream;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;

public class PersistenceManager
{
  private static SessionFactory sessionFactory = null;

  private static PersistenceManager singleton = null;

  public static PersistenceManager getInstance()
  {
    if (singleton == null)
    {
      singleton = new PersistenceManager();
    }

    return singleton;
  }

  public SessionFactory getSessionFactory()
  {
    if (sessionFactory == null)
      createSessionFactory();
    return sessionFactory;
  }

  protected void createSessionFactory()
  {    
    sessionFactory = new AnnotationConfiguration().configure()
      .buildSessionFactory();
  }

  public void destroySessionFactory()
  {
    if (sessionFactory != null)
    {
      sessionFactory.close();
      sessionFactory = null;
    }
  }
}

示例 1:

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;

public Users Login( String username,  String password)
  {
    Session session = null;
    try
    {
      String hql = "select u from Users u where u.username like :p1 and u.password like :p2";
      session = PersistenceManager.getInstance().getSessionFactory().openSession();

      Query q = session.createQuery(hql)
        .setParameter("p1", username)
        .setParameter("p2", password);

      if (q.list().size() == 0)
      {
        session.close();
        return new Users();
      }

      Users user = (Users)q.list().get(0);
      session.close();
      return user;
    }
    catch (Exception e)
    {
      session.close();
     
    }
  }

示例 2:

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
 public String Registration(Users u) { 

    Session session = null;
    try
    {
      String hql = "select u from Users u where u.username like :p1";

      session = PersistenceManager.getInstance().getSessionFactory().openSession();

      Query q = session.createQuery(hql).setParameter("p1", u.getUsername());

      if (q.list().size() == 0)
      {
        session.beginTransaction();
        session.persist(u);
        session.getTransaction().commit();
        session.close();
        return new Boolean(true).toString();
      }

      session.close();

      return new Boolean(false).toString();
    }
    catch (Exception e)
    {
      return e.toString();
    }
  }

【讨论】:

  • 您介意发布您的 my.cnf 吗?我很久以前就遇到过这些超时问题,并且能够通过使用 my.cnf 来解决它。我的托管公司升级了我的服务器并保留了我的 MySQL 配置,现在我又发现了错误,不记得我做了什么
  • +1,帮我省了很多毛头调试!
  • @Haris,,....我已经实现了 c3p0 ......但我仍然遇到同样的错误......你能帮忙......我如何优化这个 c3p0配置...?
  • 你能帮帮我吗.....我怎样才能做一个理想的c3p0配置,这样连接就不会掉线。
【解决方案2】:

我遇到了同样的问题,只是因为我忘记将我的休眠代码包装在事务中。 显然,在您提交事务之前,与 DB 的连接不会关闭。 这是一个有效的例子:

Session session = HibernateUtils.getSession();
Transaction tx = session.beginTransaction();
Category cat = null;

try{
    cat = (Category)session.get(Category.class, 1);
    tx.commit();
}catch(Exception ex){
    tx.rollback();
}finally{           
    session.close();
}

return cat;

【讨论】:

    猜你喜欢
    • 2013-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多