Повышение производительности NHibernate при слишком большом количестве объектов в сеансе - PullRequest
2 голосов
/ 03 марта 2011

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

Сессия заканчивается тем, что приходится поддерживать около 1000 или более объектов, и наше профилирование показало, что автоматическая очистка и грязная проверка являются самыми большими нарушителями здесь.Мы попытались отключить автоматическую очистку и управлять ею самостоятельно в операциях сохранения / обновления, но это привело к катастрофической производительности при пакетном сохранении / обновлении.Сейчас мы рассматриваем возможность удаления ненужных объектов из сеанса.

  1. Я столкнулся с методом вытеснения кеша 2-го уровня (sessionFactory.Evict(typeof(Cat));), который позволяет нам выселять по типу, но мы не используем кеш 2-го уровня.Могу ли я по-прежнему использовать этот метод для удаления объектов из кэша 1-го уровня?
  2. Я также читал об одном шаблоне выборки объектов, удаления их из сеанса, а затем повторной привязки их, при необходимости, к сеансу путем вызова Update () на них.Является ли это рекомендуемым и принятым шаблоном, потому что я также прочитал, что NH3 поднял стену к этому?(Мы все еще можем использовать его, поскольку мы не обновили до NH3)

Хотя мы понимаем, что мы не используем NHibernate наилучшим образом, мы просто пытаемся как-то улучшить текущую ситуацию.Ответы на вышеуказанные вопросы и любые другие предложения / рекомендации с благодарностью.Спасибо.

Обновление
После просмотра документации и кода NH, я понимаю, что 1, вероятно, невозможно.Я все еще смотрю на некоторые указатели или советы по использованию Evict ().Мне удалось резко сократить количество объектов в сеансе.Но все еще не знаю, стоит ли платить за обновление или удаление выселенных объектов.Заранее спасибо за помощь.

Ответы [ 3 ]

3 голосов
/ 03 марта 2011

Трудно сказать, не зная больше о ваших требованиях, но, возможно, вы могли бы использовать IStatelessSession. У него нет кеша 1-го уровня, о котором стоит беспокоиться.

У Айенде есть хорошая статья об использовании его для массовых операций. здесь

0 голосов
/ 23 октября 2013

Я знаю, что это старо, но я просто наткнулся на это, когда искал что-то еще - только что решил это. Я решил, как сказал Трент, используя более одного сеанса. Я бы создал один сеанс для получения всех нужных мне объектов, а затем закрыл этот сеанс. Случай, который у меня был, заключался в итерациях по списку, работе с каждым объектом и попытке фиксации на каждой итерации. Затем я создал бы foreach поверх своего списка, создав и разместив новый сеанс внутри цикла, снова подключив мой объект из списка к новому сеансу. Это заняло примерно 2,5 часа, 2 минуты 40 секунд!

См. Эту статью для вдохновения в то, как я решил это - хотя не совсем так, как у меня есть обертки единицы работы вокруг NHibernate:

http://weblogs.asp.net/ricardoperes/archive/2013/03/21/attaching-disconnected-entities-in-nhibernate-without-going-to-the-database.aspx

0 голосов
/ 04 марта 2011

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

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