关于 Hibernate session.flush() 的问题

2022-09-01 12:51:07

我想询问在以下情况下刷新方法的实际作用:

for (int i = 0; i < myList.size(); i++) {
    Car c = new Car( car.get(i).getId(),car.get(i).getName() );
    getCurrentSession().save(c);
    if (i % 20 == 0)
        getCurrentSession().flush();
}

这是否意味着在迭代 20 之后,缓存被刷新,然后 20 个保留的内存对象实际上保存在数据库中?

有人可以向我解释当情况属实时会发生什么吗?


答案 1

Session#flush 的 javadoc:

强制刷新此会话。必须在工作单元结束时调用,然后才能提交事务并关闭会话(取决于刷新模式Transaction.commit() 调用此方法)。

刷新是将基础持久性存储与内存中保存的持久状态同步的过程。

换句话说,告诉 Hibernate 执行将 JDBC 连接的状态与会话级高速缓存中保存的对象的状态同步所需的 SQL 语句。条件将使它发生在每20的倍数。flushif (i % 20 == 0)i

但是,新实例仍将保存在会话级缓存中,对于大实例,您将消耗所有内存并最终获得.为了避免这种情况,文档中描述的模式是定期(与 JDBC 批大小相同)和会话,以保留更改,然后分离实例,以便可以对它们进行垃圾回收:CarmyList.size()OutOfMemoryExceptionflushclear

13.1. 批量插入

当创建新对象时,请持续 flush() 然后定期清除() 会话,以控制第一级缓存的大小。

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();

for ( int i=0; i<100000; i++ ) {
    Customer customer = new Customer(.....);
    session.save(customer);
    if ( i % 20 == 0 ) { //20, same as the JDBC batch size
        //flush a batch of inserts and release memory:
        session.flush();
        session.clear();
    }
}

tx.commit();
session.close();

文档在同一章中提到了如何设置 JDBC 批大小。

另请参见


答案 2

取决于 FlushMode 的设置方式。

在默认配置中,休眠尝试在三个位置与数据库同步。

1. before querying data
2. on commiting a transaction
3. explictly calling flush

如果 设置为 FlushMode.Manual,则程序员通知休眠,他/她将处理何时将数据传递到数据库。在此配置下,调用会将对象实例保存到数据库中。FlushModesession.flush()

可以精确地调用来清除持久性上下文。session.clear()


推荐