Наилучшая практика: когда начинать новый сеанс / транзакцию для пакетных заданий с использованием Spring / Hibernate и когда фиксировать / очищать сеанс? - PullRequest
0 голосов
/ 22 июня 2011

Весной я дал совет по передаче транзакции вокруг моих методов обслуживания. Так, скажем, в моем пакетном классе я вызываю сервисный метод, чтобы загрузить список объектов и вернуть его в мой пакетный класс. Затем в моем пакетном классе я вызываю сервисный метод для обработки каждого из этих объектов. Но я получу исключение при отложенной загрузке, если этот метод службы попытается получить доступ к отложенному загруженному свойству объекта, так как этот список объектов был загружен с другим сеансом гибернации.

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

Мысли об этом?

Другой вопрос, который у меня возник, состоял в том, должен ли каждый из этих объектов быть независимыми друг от друга, должен ли я сохранять или не сохранять каждый объект по одному, а не сохранять их все сразу или пакетировать их. Если записано 5000 записей, кажется, что приложение сильно замедляет работу при вызове сохранения / обновления / вставки, поскольку все еще выполняет все это в памяти в сеансе Hibernate. Но если я вместо этого сохраняю / обновляю / вставляю каждую запись (обрабатывая один идентификатор за раз), а затем фиксирую, когда это делается с этим объектом перед переходом к следующему, это, похоже, значительно ускоряет. Также, если я сделаю это, скажем, каждые 200 или даже сделаю все 5000 сразу, если одна запись не будет вставлена ​​/ обновлена ​​и получит ошибку, ничего не будет сохранено, и все откатится.

Каковы лучшие практики для обработки таких вещей? Похоже, что-то действительно общее. Спасибо

Ответы [ 2 ]

0 голосов
/ 22 июня 2011

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

Что касается вопроса загрузки объекта,

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

кажется правильным.

0 голосов
/ 22 июня 2011

Прежде всего, Spring / Hibernate на самом деле не предназначен для пакетной обработки.Вместо этого, проверьте Talend или Pentaho (если вы в открытом исходном коде), или любой из огромного (огромного!) Разнообразного коммерческого инструмента.Любой из этих инструментов можно использовать для автоматической генерации кода Java, который будет выполнять именно то, что вам нужно (включая оптимизацию вставки, элегантную обработку ошибок и т. Д.).

Хорошо, давайте предположим, что вы действительно, действительно хотитезаставить Spring / Hibernate делать пакетную обработку.У вас есть несколько разных проблем - во-первых, жизненный цикл сеанса Hibernate означает, что загруженные объекты ожидают быть привязанными к живому сеансу.Вы можете использовать сеанс flush (), чтобы заставить изменения распространяться в базу данных.Сеанс close () уничтожит все.Уже загруженные объекты могут быть с трудом присоединены к новому сеансу (обычно проще просто перезагрузить объект).Если вы не закроете () / flush () сеанс, в конечном итоге у вас (вероятно) будет нехватка памяти.Это можно исправить, добавив кэш Hibernate 2-го уровня ... но это только усложнит ситуацию и замедлит ее.

Нет реальной причины не просто выполнять каждую вставку в независимом сеансе Hibernate (открыть, сделать работу, закрыть).Он не будет таким же быстрым, как специализированный инструмент, но он прост, будет работать нормально и более или менее хорош, как вы получите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...