【问题标题】:How to properly close and open a Hibernate session?如何正确关闭和打开 Hibernate 会话?
【发布时间】:2013-05-11 17:33:49
【问题描述】:

我有以下方法,每隔几秒插入大量记录。运行一段时间后,出现如下错误:

错误:通信链路故障

从服务器成功接收到的最后一个数据包是 523 毫秒前。最后一个成功发送到服务器的数据包是 8 毫秒前。

2013 年 5 月 16 日上午 9:48:30 com.mchange.v2.c3p0.stmt.GooGooStatementCache checkinStatement INFO:签入语句有问题,正在丢弃。

com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: 语句关闭后不允许任何操作。


我用来打开和关闭连接的代码如下:

public DataControllerImp() {
    session = HibernateUtil.getSessionFactory().openSession();
}

@Override
public void saveMessage(ArrayList<Message> messages) {
    Transaction tx = session.beginTransaction();

    for (int i = 0; i < mesages.size(); i++) {
        Message message = messages.get(i);

        try {
            session.save(message);
            if (i % 75 == 0) { 
                // flush a batch of inserts and release memory:
                session.flush();
                session.clear();
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            session.close();
        }
    }

    tx.commit();
}


我也在使用 c3p0 连接池。我的配置如下:

<property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>        
<property name="hibernate.c3p0.acquire_increment">1</property>
<property name="hibernate.c3p0.idle_test_period">300</property>
<property name="hibernate.c3p0.min_size">3</property>
<property name="hibernate.c3p0.max_size">20</property>
<property name="hibernate.c3p0.max_statements">50</property>
<property name="hibernate.c3p0.timeout">300</property>
<property name="hibernate.c3p0.acquireRetryAttempts">1</property>
<property name="hibernate.c3p0.acquireRetryDelay">250</property>


我是否错误地打开和关闭连接?请让我知道我可以进行哪些更改以停止接收此错误并停止我的程序。

【问题讨论】:

标签: hibernate transactions database-connection c3p0 hibernate-session


【解决方案1】:

而是为任何对象类型创建一个通用方法并传递该对象。也添加任何列表的逻辑。

public void save(Object obj) {
    Session session = null;
    Transaction transaction = null;
    try {
        session = sessionFactory.getCurrentSession();
        transaction = session.beginTransaction();
        session.save(obj);
        session.flush();
        transaction.commit();
    } catch (JDBCException jde) {
        logger.fatal("Error occured in database communication", jde);
        transaction.rollback();
        throw new RuntimeException(jde);
    } finally {
        if (session.isOpen()) {
            session.close();
        }
    }
}

【讨论】:

  • 检查以确保 session 在 finally 块中不为空(以防 getCurrentSession 抛出异常)
【解决方案2】:
    Transaction tx = session.beginTransaction();
    try {
        for (int i = 0; i < mesages.size(); i++) {
            Message message = messages.get(i);
            session.save(message);
            if (i % 75 == 0) { 
                // flush a batch of inserts and release memory:
                session.flush();
                session.clear();
            }
        }
        tx.commit();
    }catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        tx.rollBack();
    }finally{
        session.close();
    }
}

【讨论】:

  • 每次调用这个方法都会关闭连接?这真的是放置关闭语句的正确位置吗?
  • 您收到异常,因为您在提交之前关闭了会话。大约要关闭会话,这取决于工作单元,理想的场景是每个线程打开和关闭一次会话。
猜你喜欢
  • 1970-01-01
  • 2018-09-27
  • 2012-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-17
  • 1970-01-01
相关资源
最近更新 更多