NHibernate и потенциальные проблемы с кэшированием

#wcf #nhibernate

#wcf #nhibernate

Вопрос:

Итак, у меня n-уровневая модель. (WPF, Asp.Net и т.д.) Для внутренних служб через WCF. Эти службы используют NHibernate для связи с базой данных. Некоторые из этих служб будут запущены в InstanceContextMode.Одиночный режим.

Вопросы:

  1. В экземплярах одноэлементной службы должен ли я пытаться использовать 1 объект сеанса в течение всего времени работы службы wcf, чтобы получить максимальную отдачу от моего кэша?
  2. Если я использую 1 экземпляр сеанса в этом экземпляре singleton и никогда не создаю новые, я предполагаю, что мне нужно беспокоиться о том, чтобы в конечном итоге удалить кэшированные объекты из сеанса или сбросить все это вместе, чтобы избежать проблем с производительностью сеанса?
  3. Хорошая ли вообще идея использовать сеанс таким образом для одноэлементной службы wcf? Похоже, что это было бы, если бы я захотел использовать кэширование.
  4. Должен ли я использовать кэш 2-го уровня в подобном сценарии?
  5. Вне этого сценария, когда мне следует избегать кэширования? Я бы предположил, что я хотел бы избежать этого в любом сценарии пакетной обработки, когда создается / обновляется большое количество объектов и никогда больше не используется вне процесса создания или обновлений.
  6. Кэшируются ли элементы автоматически в сеансе при создании / чтении / обновлении / удалении или мне нужно что-то указать в файлах сопоставления или конфигурации?

Ответ №1:

1-3: Насколько я знаю, объекты ISession должны быть легковесными, недолговечными объектами, которые живут только в течение того времени, для которого они необходимы. Я бы не советовал использовать один и тот же объект ISession на протяжении всего срока службы вашего сервиса.
Вместо этого я бы предложил использовать тот же экземпляр ISeessionFactory и при необходимости создавать из него новые ISessions (вы можете попробовать что-то похожее на шаблон Session-Per-Request).
Если вы включите кэш 2-го уровня, вы сможете воспользоваться всеми преимуществами кэширования в этом сценарии.

5 Да, в значительной степени. Также помните, что экземпляр кэша 2-го уровня относится к экземпляру ISessionFactory. это означает, что если вы используете более 1 экземпляра ISessionFactory, у вас возникнет множество проблем с вашим кэшем.

6 для кэша 1-го уровня вам не нужно ничего определять.
для кэша 2-го уровня вам необходимо включить кэш при настройке NHibernate (в моем случае свободно):

 .Cache(c => c.UseQueryCache()
                                    .ProviderClass(
                                    isWeb ? typeof(NHibernate.Caches.SysCache2.SysCacheProvider).AssemblyQualifiedName //in web environment- use sysCache2
                                        : typeof(NHibernate.Cache.HashtableCacheProvider).AssemblyQualifiedName //in dev environmet- use stupid cache
                                    )) 
                          )
  

и укажите для каждого объекта и каждой коллекции, что вы хотите включить для них кэширование:

 mapping.Cache.ReadWrite().Region("myRegion");
  

и для коллекции:

 mapping.HasMany(x => x.Something)
.Cache.ReadWrite().Region("myRegion");
  

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

1. Если я использую кэш 2-го уровня, нужно ли мне беспокоиться о # 2 выше? Также, если я определю свои объекты с кэшированием, пока я все еще смогу включить / отключить это поведение через config?

2. в принципе, no- NHibernate управляет кэшем с точки зрения проверки / аннулирования, очистки и т.д. И да — кэширование настраивается (опубликованный мной беглый код, конечно, может быть записан в виде конфигурации XML).