Hibernate Batch Insert是如何工作的?

omvjsjqw  于 2022-11-14  发布在  其他
关注(0)|答案(3)|浏览(166)

有人能解释一下我是怎么

hibernate.jdbc.batch_size = 1000

if (i % 100 == 0 && i > 0) {
    session.flush();
    session.clear();
}

一起工作吗?

erhoui1w

erhoui1w1#

Hibernate属性hibernate.jdbc.batch_size是Hibernate优化INSERT或UPDATE语句的一种方法,而刷新循环是关于内存耗尽的。
没有BatchSize,当您尝试保存实体时,Hibernate Fire 1 INSERT语句,因此,如果您使用的是一个大集合,则对于每个SAVE Hibernate Fire 1语句。
想象一下下面这段代码:

for (Entity e : entities) {
    session.save(e);
}

在这里,Hibernate将为集合中的每个实体触发一条INSERT语句。如果您的集合中有100个元素,则将激发100个INSERT语句。这种方法效率不高,主要有两个原因:
1.以指数级增加一级缓存,很可能很快就会得到OutOfMemoryException
1.每条语句的网络往返会降低性能。
hibernate.jdbc.batch_size和冲洗环路有两个不同的用途,但是互补的。
Hibernate使用第一个参数来控制批处理的实体数量。在封面下,Hibernate使用java.sql.Statement.addBatch(...)executeBatch()方法。
因此,hibernate.jdbc.batch_size告诉Hibernate在调用executeBatch()之前它必须调用addBatch()多少次。

  • 因此,设置此属性并不能防止内存耗尽。*

为了管理内存,您必须定期刷新会话,这就是刷新循环的目的。
当你写下这封信时:

for (Entity e : entities) {
    if (i % 100 == 0 && i > 0) {
        session.flush();
        session.clear();
    }
}

您告诉Hibernate每隔100个实体刷新和清除会话(您释放内存)。

那么现在两者之间的联系是什么?

为了达到最佳效果,您必须将jdbc.batch_size和刷新参数定义为相同。
如果您定义的刷新参数低于您选择的BATCH_SIZE,那么Hibernate将更频繁地刷新会话,因此它将创建小批处理,直到它达到批处理大小,这是低效的。
当两者相同时,如果集合的大小不是Batch_Size的倍数,则Hibernate将只执行大小最优的批处理,最后一个除外。
您可以查看下面的post以了解有关最后一点的更多详细信息。

6jygbczu

6jygbczu2#

hibernate.jdbc.batch_size确定执行的最大批处理大小。如果在达到指定的批处理大小(the same table的挂起INSERT或UPDATE语句数)之前执行隐式或显式刷新,则所有挂起的语句都打包在一个批处理中,并重新开始语句的“累积”。
因此,在您的示例中,您将执行每个包含100条语句的批处理。或者,例如,如果批处理大小为100,模除数为500,则在执行刷新操作时,您将执行5个批处理,每个批处理包含100条语句。

1yjd4xko

1yjd4xko3#

批处理允许您将相关的SQL语句分组为批处理,并通过一次数据库调用提交它们。

为什么我们需要

请务必记住,添加到语句或PreparedStatement中的每个更新都是由数据库单独执行的。这意味着,他们中的一些人可能会在其中一个人失败之前成功。所有已成功的语句现在都已应用到数据库,但其余的更新可能不会。这可能会导致数据库中的数据不一致。
为了避免这种情况,您可以在事务内执行批处理更新。在事务内执行时,您可以确保执行所有更新,或者不执行任何更新。任何成功的更新都可以回滚,以防其中一个更新失败。

什么是批处理和刷新

批量大小和冲洗是不同的事情。当您将hibernate.jdbc.batch_size设置为1000时,这意味着Hibernate将执行批插入或最多更新1000实体。在提交事务之前,可以使用flush操作将所有更改写入数据库
如果您的批处理大小设置为1000,并且您每刷新100个实体,Hibernate将执行许多小批处理,每小批100个INSERT或UPDATE语句执行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?

相关问题