NHibernate кэширование второго уровня с несколькими запросами
Мы широко используем функцию множественных запросов NHibernate и испытываем странное поведение. Похоже, что NHibernate не кэширует мультизапросы, и они всегда попадают в базу данных. Мы используем QueryOver, все запросы настроены для кэширования, но при тестировании домашней страницы с помощью http://blitz.io/ с -p 1-250:30
Я вижу, что единственный мультизапрос, попадающий в базу данных, выполняется более 2000 раз, тогда как другие запросы (например, выбор текущего зарегистрированного пользователя) выполняются только один или два раза.
Итак, вопрос: я что-то упустил или NHibernate на самом деле не кеширует результаты нескольких запросов?
1 ответ
Ага, понял! Как выяснилось, это была ошибка не всего кэша второго уровня, а, скорее, виноват наш способ использования QueryOver.
Поскольку мы пишем мультитенантное SaaS-приложение, большинство наших запросов выглядят так:
return
Session.QueryOver<Article>().Cacheable().
Where(a => a.Site == site && a.PublishedAt <= publishedAt).
OrderByCoalesceDesc(typeof(DateTime), a => a.UpdatedAt, a => a.CreatedAt).
Take(count).
Future();
А также a.Site == site
была проблема. Очевидно, способ кеширования запросов проверяет, кэшируются ли результаты запроса, или нет, в основном, используя комбинацию оператора SQL и всех параметров в качестве ключа к кешу "hashtable". Текст оператора SQL всегда одинаков для наших мультизапросов, но site
параметр был виновником. NH проверяет, соответствуют ли все предоставленные параметры тем, которые уже находятся в кэше, и, естественно, у нас нет Equals()
реализовано в нашем Site
класс, поэтому проверка всегда не удалась.
В итоге мы переписали наши запросы так:
var siteID = site.ID;
return
Session.QueryOver<Article>().Cacheable().
Where(a => a.Site.ID == siteID && a.PublishedAt <= publishedAt)...