3.4.6. Кэши сущностей и запросов
- Кэш сущностей (Entity Cache)
-
Кэш сущностей предоставляется ORM фреймворком EclipseLink. Он хранит в памяти недавно прочитанные или записанные экземпляры сущностей, тем самым сокращая доступ к базе данных и увеличивая производительность.
Кэш сущностей используется только при извлечении сущностей по идентификатору, поэтому запросы по другим атрибутам по-прежнему выполняются на базе данных. Тем не менее, эти запросы могут стать проще и быстрее, если связанные сущности находятся в кэше. Например, если вы запрашиваете Заказы вместе со связанными Заказчиками, и не используете кэш, то SQL-запрос будет содержать JOIN с таблицей заказчиков. Если же сущность Заказчик закэширована, SQL-запрос будет только по таблице заказов, а связанные заказчики будут извлечены из кэша.
Для того, чтобы включить кэш сущностей, установите следующие свойства приложения в файле app.properties модуля core вашего проекта:
-
eclipselink.cache.shared.sales_Customer = true
- включает кэширование сущностиsales_Customer
. -
eclipselink.cache.size.sales_Customer = 500
- устанавливает размер кэша для сущностиsales_Customer
в 500 экземпляров.Если кэширование включено, всегда рекомендуется увеличить размер кэша (по умолчанию - 100). В противном случае, если запрос вернёт более 100 записей, то каждая запись будет извлечена отдельной операцией.
Факт кэширования сущности влияет на то, какой fetch mode выбирается платформой при загрузке графов сущностей. Если некоторый ссылочный атрибут представляет собой кэшируемую сущность, то fetch mode всегда будет
UNDEFINED
, что позволяет ORM извлекать ссылку из кэша вместо добавления в запрос JOIN или выполнения отдельного batch-запроса.Платформа обеспечивает координацию кэша сущностей в кластере middleware. Когда кэшированный экземпляр сущности обновляется или удаляется на одном узле кластера, тот же экземпляр на других узлах (если он загружен) будет инвалидирован, что приведет к загрузке свежего состояния из БД при следующей операции с данным экземпляром.
-
- Кэш запросов (Query Cache)
-
Кэш запросов сохраняет идентификаторы экземпляров сущностей, возвращаемых JPQL-запросами, тем самым естественно дополняя кэш сущностей.
Например, если для сущности
sales_Customer
разрешен entity cache, и запросselect c from sales_Customer c where c.grade = :grade
выполняется первый раз, происходит следующее:-
ORM выполняет запрос в базе данных.
-
Загруженные экземпляры сущности
Customer
помещаются в entity cache. -
В кэш запросов помещается соответствие между текстом запроса вместе с параметрами и списком идентификаторов загруженных экземпляров.
Когда этот же запрос с такими же параметрами выполняется второй раз, платформа находит запрос в кэше запросов и загружает экземпляры сущностей по идентификаторам из кэша сущностей, не обращаясь к базе данных.
Запросы по умолчанию не кэшируются. Указать, что запрос должен кэшироваться, можно на различных уровнях приложения:
-
Методом
setCacheable()
интерфейса Query при работе с EntityManager. -
Методом
setCacheable()
интерфейсаLoadContext.Query
при работе с DataManager. -
Методом
setCacheable()
интерфейсаCollectionLoader
или в XML-атрибутеcacheable
при работе с загрузчиками данных.
Кэшируемые запросы следует использовать только если для возвращаемой сущности разрешен entity cache. В противном случае при каждом запросе экземпляры сущности будут загружаться из базы данных по идентификаторам по одному.
Кэш запросов автоматически инвалидируется, когда через ORM выполняются операции создания, изменения или удаления с сущностями соответствующего типа. Инвалидация работает по всему кластеру среднего слоя.
JMX-бин
app-core.cuba:type=QueryCacheSupport
можно использовать для мониторинга состояния кэша и для удаления запросов из кэша. Например, если вы изменили некоторый экземпляр сущностиsales_Customer
напрямую в БД, необходимо удалить все закэшированные запросы по этой сущности с помощью операцииevict()
с аргументомsales_Customer
.На поведение кэша запросов оказывают влияние следующие свойства приложения:
-