NHibernate кэш второго уровня автоматически очищается NHibernate в веб-сервисе - PullRequest
0 голосов
/ 27 февраля 2020

Я использую SysCache2 в качестве поставщика кэша второго уровня для NHibernate. Вот тестовый код:

`ISession session = NHibernateHelper.GetSession();
Model.Task t1 = session.Get<Model.Task>("e84wqbarscj5");
richTextBox1.AppendText(t1.BuyerAccount.BuyerName);
session.Close();`

При первом запуске тестового кода консоль показывает, что NHibernate дважды выполнил запрос sql. При повторном запуске тестового кода консоль показывает, что NHibernate не выполнил никаких запросов SQL. И я думаю, это указывает на то, что кэш второго уровня работает правильно.

Далее, я выполняю аналогичный код в веб-сервисе, Вот код:

`AppServiceGetTaskResponse result = new AppServiceGetTaskResponse();
 ISession hSession = NHibernateHelper.GetSession();
 Model.Task task = hSession.Get<Model.Task>(request.TaskId);
 result.BuyerName = task.BuyerAccount.BuyerName;
 hSession.Close();
 retrun result;`

Я использую Http Когда клиент впервые обращается к этому веб-сервису, консоль показывает, что NHibernate дважды выполнил запрос sql. Это хорошо. Я использовал тот же клиент для доступа к веб-службе во второй раз, но на этот раз кэш второго уровня не работал должным образом. Консоль показывает, что NHibernate дважды выполнил запрос sql.

Я сделал новую попытку и изменил код следующим образом:

`AppServiceGetTaskResponse result = new AppServiceGetTaskResponse();
 ISession hSession = NHibernateHelper.GetSession();
 Model.Task task = hSession.Get<Model.Task>(request.TaskId);
 result.BuyerName = task.BuyerAccount.BuyerName;
 hSession.Close();
if (result.BuyerName != "")
            {
                hSession = NHibernateHelper.GetSession();
                task = hSession.Get<Model.Task>(request.TaskId);
                result.BuyerName = task.BuyerAccount.BuyerName;
                hSession.Close();
            }
 retrun result;`

Я использовал тот же клиент для доступа к измененному веб-сервис. На этот раз консоль показала, что NHibernate выполнил 2 sql запросов. Кэш второго уровня, похоже, снова заработал.

Наконец, я добавил журнал отладки с журналом 4net и обнаружил, что NHibernate автоматически очищает все кэши второго уровня. Потому что, если тот же код выполняется в обычной тестовой программе, автоматическая очистка c не будет выполнена, поэтому я предполагаю, что это связано с управлением потоками веб-службы или содержимого сеанса.

`NHibernate.Impl.SessionFactoryImpl:  2020-02-28 13:17:01,185 DEBUG evicting second-level cache for: Model.BuyerAccount
NHibernate.Impl.SessionFactoryImpl:  2020-02-28 13:17:01,185 DEBUG evicting second-level cache for: Model.Buyer`

Ответы [ 2 ]

0 голосов
/ 29 февраля 2020

Я решил проблему сам. В веб-сервисе есть метод записи журнала выполнения, он использует метод выполнения нативного SQL: session.CreateSQLQuery («вставить в ...»), который заставляет NHibernate автоматически выполнять операцию удаления из 2-х уровневый кеш. Вместо этого я использую метод session.save (), проблема решена. Но я не понимаю принцип, может кто-нибудь помочь мне ответить на него?

0 голосов
/ 27 февраля 2020

Кэш второго уровня поддерживается на уровне SessionFactory. В идеале, он должен быть собран только один раз для объема приложения / времени жизни. Это идеально подходит для вашего первого примера (тестовое приложение).

Во втором примере (веб-сервис), я думаю, это ломается. Я подозреваю, что ваш SessionFactory разрушается и создается снова. Вот почему кэш второго уровня поддерживается, пока первый запрос уничтожен, а для второго вызова он вызывает повторное выполнение двух запросов для построения кеша fre sh.

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

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