我想知道flush方法在下面的情况下实际上做了什么:
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个持有的内存对象实际上被保存在数据库中?
有人能告诉我当条件成立时会发生什么吗?
4条答案
按热度按时间bvjxkvbb1#
从
Session#flush
的javadoc:强制刷新此会话。必须在工作单元结束时,在提交事务和关闭会话之前调用(根据刷新模式,Transaction.commit()调用此方法)。
换句话说,
flush
告诉Hibernate执行同步JDBC连接状态和会话级缓存中对象状态所需的SQL语句。条件if (i % 20 == 0)
会使每一个20的i
倍数都发生。但是,新的
Car
示例仍将保存在会话级缓存中,对于大的myList.size()
,您将占用所有内存并最终获得OutOfMemoryException
。为了避免这种情况,文档中描述的模式是以固定的间隔(与JDBC批处理大小相同)flush
ANDclear
会话,以持久化更改,然后分离示例,以便它们可以被垃圾收集:13.1.批量插入
当使新对象持久化时,定期地flush()然后clear()会话,以控制一级缓存的大小。
文档在同一章中提到了如何设置JDBC批处理大小。
参见
cunj1qz12#
取决于冲洗模式的设置方式。
在默认配置中,Hibernate尝试在三个位置与数据库同步。
如果
FlushMode
设置为FlushMode.Manual,程序员通知hibernate他/她将处理何时将数据传递到数据库。在这种配置下,session.flush()
调用将把对象示例保存到数据库中。session.clear()
调用实际上可以用来清除持久化上下文。lyfkaqu13#
关于为什么刷新应该与批大小匹配的更多提示要启用刷新,您需要设置jdbc批大小
在使用SQL的过程中,一个常见的陷阱是如果你使用的是单个对象update或insert,这很好。但是如果你使用的是多个对象,导致多个insert/update,那么你就必须显式地设置排序机制。
例如
在这种情况下,生成了两个SQL 1用于插入汽车1用于插入附件
为了正确的安装,您必须设置
这样所有car的insert和所有accessories的insert就被排序在一起了。这样你就有20个insert在一个批次中触发,而不是一次触发1个sql。
对于一个事务下的不同操作,您可以查看http://docs.jboss.org/hibernate/core/3.2/api/org/hibernate/event/def/AbstractFlushingEventListener.html
oipij1gg4#
是的,每20次循环,SQL都会为未保存的对象生成并执行。您还应该将批处理模式设置为20以提高性能。