Как работает Hibernate Batch?

Может кто-нибудь объяснить мне, как

hibernate.jdbc.batch_size=1000 

а также

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

вместе работает? ...

3 ответа

Спящая собственность hibernate.jdbc.batch_size это способ для hibernate оптимизировать вашу вставку или обновить формулировку, тогда как цикл очистки об исчерпании памяти.

Без пакетного размера, когда вы пытаетесь сохранить оператор hibernate fire 1 для вставки, то есть, если вы работаете с большой коллекцией, для каждого оператора save hibernate fire 1

Представьте себе следующий фрагмент кода:

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

Здесь hibernate будет запускать 1 оператор вставки для каждой сущности в вашей коллекции. если у вас есть 100 элементов в вашей коллекции, то будут вставлены 100 операторов вставки. Этот подход не очень эффективен по двум основным причинам:

  • 1) Вы увеличиваете экспоненциально кэш 1-го уровня и, вероятно, скоро закончите с OutOfMemoryException,
  • 2) Вы снижаете производительность из-за обратной связи по сети для каждого оператора.

hibernate.jdbc.batch_size и цикл очистки имеют 2 разные цели, но дополняют друг друга.

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, который вы выбираете таким образом, что hibernate будет сбрасывать сеанс чаще, так что он будет создавать небольшой пакет, пока не достигнет размера btach, что неэффективно

когда 2 одинаковы, Hibernate будет выполнять только пакеты оптимального размера, за исключением последнего, если размер коллекции не кратен вашему batch_size.

Вы можете увидеть следующий пост для более подробной информации об этом последнем пункте

hibernate.jdbc.batch_size определяет максимальный размер пакета, который будет выполнен. Если неявная или явная очистка выполняется до того, как будет достигнут указанный размер пакета (количество ожидающих операторов вставки или обновления для одной и той же таблицы), все ожидающие операторы упаковываются в один пакет, и "накопление" операторов перезапускается.

Итак, в вашем примере вы выполняете пакеты, состоящие из 100 операторов каждая. Или, например, если размер пакета равен 100, а делитель по модулю равен 500, при выполнении операции сброса вы выполняете 5 пакетов, состоящих из 100 операторов в каждой.

Пакетная обработка позволяет группировать связанные операторы SQL в пакет и отправлять их одним вызовом в базу данных.

Зачем нам

Важно помнить, что каждое обновление, добавленное в Statement или PreparedStatement, выполняется базой данных отдельно. Это означает, что некоторые из них могут преуспеть, прежде чем один из них потерпит неудачу. Все успешные операторы теперь применяются к базе данных, но остальные обновления могут отсутствовать. Это может привести к несогласованности данных в базе данных.

Чтобы избежать этого, вы можете выполнить пакетное обновление внутри транзакции. При выполнении внутри транзакции вы можете убедиться, что либо все обновления выполнены, либо нет. Любые успешные обновления могут быть отменены в случае сбоя одного из обновлений.

Что такое партия и промывка

Размер партии и промывка это разные вещи. когда вы установите hibernate.jdbc.batch_size в 1000 это означает, что Hibernate будет делать пакетные вставки или обновлять до 1000 юридические лица.flush можно использовать операцию записи всех изменений в базу данных до совершения транзакции

если размер пакета установлен равным 1000, а вы сбрасываете каждые 100 объектов, Hibernate будет выполнять множество небольших пакетов по 100 операторов вставки или обновления 10 раз.

Пожалуйста, прочитайте больше ниже этой ссылки:

http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/batch.html

Почему количество сбрасываемых объектов должно быть равно hibernate.jdbc.batch_size?

Другие вопросы по тегам