我参考了很多文章,但我仍然不清楚session.clear
在hibernate中的作用。
根据我遇到的是到目前为止,当我们使用批量保存/更新如下所示:
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将会话的内存状态与数据库同步。
问题
**1.**刷新会话后,为什么还要做session.clear()
?真的需要吗?
2.session.clear()
是否执行提交操作?
**3.**如果session.clear()
驱逐所有加载的对象,那么在执行提交和回滚操作时,内部会发生什么?
2条答案
按热度按时间jmo0nnb31#
可以将Session视为自启动当前事务以来已经从数据库加载(或持久化)的实体的缓存。
Session.clear
在任何情况下都不是强制性的,但如果您在一个事务中执行大量实体加载/保存,则会很有用,以避免内存溢出错误。在您的示例中,在会话中复制了50个employee
实体。如果没有每50个save()
调用flush
和clear
方法,您将在会话中复制100.000个实体。会话(并且不可垃圾收集,因为会话具有到实体的链接)。Session.clear
不会执行提交或回滚,甚至不会执行flush
(因此,您应该在Session.clear
之前执行flush,以便hibernate为挂起的实体更新生成sql查询)。1.回滚或提交操作不在应用程序端执行,而是在数据库中执行:Hibernate只会要求数据库提交或回滚(Hibernate可能会在提交操作之前触发刷新,但刷新不是提交的一部分)。提交操作将不会它是一种数据库内部机制,将持久化(或恢复)由于自事务开始以来运行的所有SQL查询而执行的数据修改。
完全相同的方式,在hibernate中打开一个事务并没有执行很多事情:主要是从池中获得一个db连接,并告诉数据库在sql查询之后 NOT
auto_commit
,而是等待一个commit或rollback命令。ztigrdn82#
Thierry的回答非常好。但是如果客户端有太多的并发连接和内存问题(GC)。最好的解决方案是我在这里做的:不使用Hibernate,直接使用mysql或postgres的原生JDBC连接器。