一尘不染

session.clear()在Hibernate中如何工作

hibernate

我提到了许多文章,但仍然不清楚session.clearhibernate状态下的性能。

根据我到目前为止遇到的是,当我们使用批量保存/更新时,如下所示:

Session session = SessionFactory.openSession();
Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) {
    Employee employee = new Employee(.....);
    session.save(employee);
    if( i % 50 == 0 ) { // Same as the JDBC batch size
        //flush a batch of inserts and release memory:
        session.flush();
        session.clear();
    }
}
tx.commit();
session.close();

sesion.flush(); 用于刷新会话强制Hibernate将Session的内存中状态与数据库同步。

1. 刷新会话后,为什么需要这样做session.clear()?真的需要吗?

2.session.clear()执行提交动作吗?

3. 如果session.clear()逐出所有已加载的对象,则在执行提交和回滚操作时内部会发生什么?


阅读 291

收藏
2020-06-20

共1个答案

一尘不染

可以将会话视为自开始当前事务以来已经从数据库加载(或持久存储到)的实体的缓存。

  1. Session.clear并非以任何方式强制执行,但是如果您在一个事务中执行大量实体加载/保存操作,则很有用,以避免出现内存不足错误。在您的示例中,您将employee在会话中复制50个实体。如果没有flushand clear方法调用,则每50个对象中save()您将有100.000个实体在会话中复制(并且不是垃圾回收的,因为会话具有指向该实体的链接)。

  2. Session.clear将不会执行提交或回滚。甚至都不是flush(因此,为什么您应该在之前进行刷新Session.clear,以便hibernate生成SQL查询来查询未决的实体更新。

  3. 回滚或提交操作不是在应用程序端执行的,而是在数据库中执行:hibernate只会要求数据库进行提交或回滚(Hibernate可能会在提交操作之前触发刷新,但刷新不属于提交的一部分)。提交操作将(也无法)访问会话。这是一种数据库内部机制,由于自事务开始以来运行了所有SQL查询,因此该数据库内部机制将保留(或还原)执行的数据修改。

完全以相同的方式,在hibernate状态下打开事务并没有执行很多操作:主要是从池中获取数据库连接,并告诉数据库 不要
auto_commit遵循sql查询,而是等待提交或回滚命令。

2020-06-20