транзакция в режиме гибернации фиксируется чрезвычайно медленно, когда сеанс кэширует огромные объекты

#java #hibernate

#java #спящий режим

Вопрос:

Две таблицы A (25 тыс. строк) и B (2,2 млн строк), используйте сеанс гибернации, загружайте все эти данные (каждая строка представляет один объект), затем обновляйте только одну строку в A и одну строку в B в транзакции, я обнаружил, что поведение в режиме гибернации странное: фиксация занимает около 1,5 секунд для возврата. Однако журнал базы данных sql показывает, что команда sql update занимает всего несколько миллисекунд. режим гибернации занимает большую часть времени перед сбросом команды sql в базу данных.

Поэтому я использую jprofiler, чтобы выяснить, что он делает:

процессор записывает данные

Нет никаких подсказок о том, как было потрачено время. Из-за базы данных команда обновления выполняется очень быстро, поэтому она не должна быть заблокирована базой данных. Если он выполнял вычисления, это должно быть записано jprofiler (отнимает много времени у процессора).

Что здесь делает hibernate? Почему фиксация происходит так медленно?

Комментарии:

1. У меня есть вопрос , например , почему вы загружаете целые строки для обновления одной строки?

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

Ответ №1:

Если вы загрузили более 2 миллионов объектов, которые находятся в кэше первого уровня Hibernate, вы не должны удивляться, что все происходит немного медленно. Время, скорее всего, тратится на просмотр всех этих объектов в поисках изменений. Если вы знаете, что вам не нужен объект, вы можете удалить его из кэша. Это уменьшит потребление памяти и ускорит конечную фиксацию. Просто следите за тем, чтобы не удалять объекты, которые действительно необходимы, иначе вы создадите неприятные ошибки!

Комментарии:

1. Согласен с @ewramner, я думаю, вам следует использовать отложенную загрузку или JIT.

2. Вы правы. Я выполняю отладку в режиме гибернации, обнаружив, что он выполнял грязную проверку в цикле всех 2 миллионов объектов. jprofiler не удалось зафиксировать это. Но почему в режиме гибернации все объекты грязные, проверяйте, что они кэшируются, даже если я передаю только один объект в saveOrUpdate?

3. Так оно и построено. Для пакетных заданий (а обработка 2 миллионов объектов — это пакетное задание в моей книге) вам обычно нужно обрабатывать объекты по частям и удалять по мере выполнения для хорошей производительности. Еще лучше было бы, если бы вы могли фильтровать, чтобы вы, конечно, не читали все из них вообще.