有人能解释我是怎么回事吗?
hibernate.jdbc.batch_size=1000
和
if (i % 100 == 0 && i>0) {
session.flush();
session.clear();
}
一起工作? ...
答案 0 :(得分:3)
Hibernate属性hibernate.jdbc.batch_size
是hibernate优化插入或更新状态的一种方式,而刷新循环是关于内存耗尽的。
当你尝试保存实体hibernate fire 1 insert语句时没有batchsize,因此如果你使用一个大集合,为每个保存hibernate fire 1语句
想象一下以下代码:
for(Entity e : entities){
session.save(e);
}
这里hibernate会在你的集合中为每个实体触发1个insert语句。如果你的集合中有100个元素,那么就会触发100个插入语句。 由于以下两个主要原因,这种方法效率不高:
OutOfMemoryException
完成。hibernate.jdbc.batch_size和刷新循环有两个不同的目的但是是互补的。
Hibernate使用第一个来控制批量实体的数量。在Hibernate的封面下使用java.sql.Statement.addBatch(...)
和executeBatch()
方法。
所以hibernate.jdbc.batch_size告诉hibernate在调用addBatch()
之前调用executeBatch()
的次数。
因此设置此属性并不会阻止内存耗尽。
为了处理内存,你必须定期刷新你的会话,这就是刷新循环的目的。
当你写:
for(Entity e : entities){
if (i % 100 == 0 && i>0) {
session.flush();
session.clear();
}
}
你告诉hibernate每100个实体刷新并清除会话(释放内存)。
那么现在2?
之间的联系是什么?为了达到最佳效果,您必须定义jdbc.batch_size
和您的冲洗参数相同。
如果你定义一个低于你选择的batch_size的flush参数,那么hibernate会更频繁地刷新会话,所以它会创建一个小批量,直到它达到btach大小 哪个效率不高
当2是相同的时候,如果集合的大小不是你的batch_size的倍数,那么除了最后一个之外,hibernate将只执行最佳大小的批量。
有关此最后一点的详细信息,您可以看到以下post
答案 1 :(得分:1)
hibernate.jdbc.batch_size
确定执行的最大批量大小。如果在达到指定的批处理大小(the same table的待处理插入或更新语句的数量)之前执行隐式或显式刷新,则所有挂起的语句将打包在一个批处理中,并重新启动语句的“累积”。
因此,在您的示例中,您将执行每个包含100个语句的批处理。或者,例如,如果批量大小为100且模数除法器为500,则在执行刷新操作时,您将执行5个批次,每个批次包含100个语句。
答案 2 :(得分:0)
批处理允许您将相关的SQL语句分组到批处理中,并通过一次调用数据库来提交它们。
为什么我们需要
请务必记住,添加到Statement或PreparedStatement的每个更新都由数据库单独执行。这意味着,其中一些可能会在其中一个失败之前成功。已成功的所有语句现在都应用于数据库,但其余更新可能不适用。这可能导致数据库中的数据不一致。
为避免这种情况,您可以在事务中执行批量更新。在事务内执行时,您可以确保执行所有更新,或者不执行任何更新。如果其中一个更新失败,则可以回滚任何成功的更新。
什么是批处理和刷新
批量大小和冲洗是不同的事情。当您将hibernate.jdbc.batch_size
设置为1000
时,这意味着hibernate将执行批量插入或更新到1000
个实体。flush
操作可用于在事务之前写入对数据库的所有更改承诺
如果批量大小设置为1000,并且每100个实体刷新一次,Hibernate将执行10次小批量的100次插入或更新语句10次。
请在此链接下方阅读更多内容:
http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/batch.html
Why number of objects being flushed should be equal to hibernate.jdbc.batch_size?