我提到了许多文章,但仍然不清楚session.clearhibernate状态下的性能。
session.clear
根据我到目前为止遇到的是,当我们使用批量保存/更新时,如下所示:
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的内存中状态与数据库同步。
sesion.flush();
题
1. 刷新会话后,为什么需要这样做session.clear()?真的需要吗?
session.clear()
2. 会session.clear()执行提交动作吗?
3. 如果session.clear()逐出所有已加载的对象,则在执行提交和回滚操作时内部会发生什么?
可以将会话视为自开始当前事务以来已经从数据库加载(或持久存储到)的实体的缓存。
Session.clear并非以任何方式强制执行,但是如果您在一个事务中执行大量实体加载/保存操作,则很有用,以避免出现内存不足错误。在您的示例中,您将employee在会话中复制50个实体。如果没有flushand clear方法调用,则每50个对象中save()您将有100.000个实体在会话中复制(并且不是垃圾回收的,因为会话具有指向该实体的链接)。
Session.clear
employee
flush
clear
save()
Session.clear将不会执行提交或回滚。甚至都不是flush(因此,为什么您应该在之前进行刷新Session.clear,以便hibernate生成SQL查询来查询未决的实体更新。
回滚或提交操作不是在应用程序端执行的,而是在数据库中执行:hibernate只会要求数据库进行提交或回滚(Hibernate可能会在提交操作之前触发刷新,但刷新不属于提交的一部分)。提交操作将(也无法)访问会话。这是一种数据库内部机制,由于自事务开始以来运行了所有SQL查询,因此该数据库内部机制将保留(或还原)执行的数据修改。
完全以相同的方式,在hibernate状态下打开事务并没有执行很多操作:主要是从池中获取数据库连接,并告诉数据库 不要 auto_commit遵循sql查询,而是等待提交或回滚命令。
auto_commit