Мне трудно понять, когда спящий режим попадает во второй уровень кеша, а когда он делает недействительным кеш.
Вот что я сейчас понимаю:
- Кэш второго уровня хранит объекты между сеансами, область действия - SessionFactory
- Вы должны указать, какие объекты кэшировать, по умолчанию никакие объекты не будут кэшироваться.
- Кэш запросов хранит результаты запросов в кеше.
Я не понимаю
- Когда спящий режим попадает в этот кеш?
- Допустим, я установил кеш второго уровня, но не кеширование запросов. Я хочу кэшировать своих клиентов, их 50000. Как я могу получить клиентов из кеша?
- Я предполагаю, что могу получить их по идентификатору из кеша. Это было бы легко, но кешировать не стоит. Но что, если я хочу произвести какие-то расчеты со всеми своими клиентами. Допустим, я хочу показать список клиентов, тогда как мне получить к ним доступ?
- Как мне получить всех своих клиентов, если кеширование запросов отключено?
- Что будет, если кто-то обновит одного из клиентов?
- Будет ли этот клиент признан недействительным в кеше или все клиенты станут недействительными?
Или я считаю кеширование совершенно неправильным? Что было бы более подходящим использованием кеша второго уровня в этом случае? В документации по гибернации вообще не понятно, как кеш работает на самом деле. Есть только инструкции по его настройке.
Обновление: Итак, я понял, что кеш второго уровня (без кеша запросов) был бы хорош для загрузки данных по идентификатору. Например, у меня есть пользовательский объект, разрешения на который я хочу проверять в каждом запросе в веб-приложении. Будет ли это хорошим случаем для уменьшения доступа к базе данных путем кэширования пользователя в кеш второго уровня? Как будто я сохраняю идентификатор пользователя в сеансе или где угодно, и когда мне нужно проверить разрешения, я загружал пользователя по его идентификатору и проверял разрешения.
Ответы:
Прежде всего, давайте поговорим о кеш-памяти уровня процесса (или кеш-памяти 2-го уровня, как его называют в Hibernate). Чтобы это работало, вы должны
Вы сообщаете поставщику кеша, сколько объектов он должен хранить и когда / почему они должны быть признаны недействительными. Итак, допустим, у вас есть сущности Book и Author, каждый раз, когда вы получаете их из БД, только те, которые не находятся в кеше, будут выбираться из фактической БД. Это значительно увеличивает производительность. Это полезно, когда:
Итак, когда работает кеш?
session.get()
илиsession.load()
объект, который был выбран ранее и находится в кеше. Кэш - это хранилище, в котором идентификатор является ключом, а свойства - значениями. Таким образом, только когда есть возможность поиска по идентификатору, вы можете исключить попадание в БД.Но не работает, когда:
from Authors where name = :name
то вы не попадаете в кеш.where id = ?
).fetch="join"
, это означает, что для загрузки ассоциаций везде будут использоваться объединения вместо отдельных операторов выбора. Кэш уровня процесса работает с дочерними объектами, только еслиfetch="select"
он используется.fetch="select"
но тогда в HQL вы используете объединения для выбора ассоциаций - эти объединения будут выданы сразу, и они перезапишут все, что вы указали в hbm.xml или аннотациях.Теперь о кэше запросов. Обратите внимание, что это не отдельный кеш, это дополнение к кешу уровня процесса. Допустим, у вас есть организация Country. Это статично, поэтому вы знаете, что каждый раз, когда вы говорите, будет один и тот же набор результатов
from Country
. Это идеальный кандидат для кеширования запросов, он будет хранить в себе список идентификаторов , и когда вы в следующий раз выберете все страны, он вернет этот список в кеш уровня процесса, а последний, в свою очередь, вернет объекты для каждого идентификатора поскольку эти объекты хранятся уже в кеше 2-го уровня. Кэш запросов становится недействительным каждый раз, когда изменяется что-либо, связанное с сущностью. Предположим, вы настроилиfrom Authors
размещение в кэше запросов. Это не сработает, поскольку Автор часто меняется.источник
На самом деле полезно иметь распределенный кеш по ключу - это то, что такое memcached, и он поддерживает facebook, twitter и многие другие. Но если у вас нет поисков по идентификатору, то это будет не очень полезно.
источник
Поздно к вечеринке, но хотел систематически ответить на этот вопрос, который задают многие разработчики.
Я отвечу на ваши вопросы один за другим.
A. Кэш первого уровня связан с объектом сеанса . Второй уровень кэша связан с объектом Factory Session . Если объект не найден на первом, то проверяется второй уровень.
A. Вы ответили на этот вопрос в своем обновлении. Кроме того, в кэше запросов хранится только список идентификаторов объекта, а эти объекты со своими идентификаторами хранятся в том же кэше второго уровня. Поэтому, если вы включите кеширование запросов, вы будете использовать тот же ресурс. Аккуратно, правда?
А. Ответил выше.
А. Ответил выше.
A. Hibernate понятия не имеет, но вы можете использовать другие сторонние IMDG / распределенные кеши, которые будут реализованы как кеш второго уровня спящего режима и сделать их недействительными. например, TayzGrid - один из таких продуктов, и я думаю, что их гораздо больше.
источник
Кэш второго уровня Hibernate немного сложно понять и реализовать. Вот что мы можем сказать по вашим вопросам:
Как вы предполагаете, кэш L2 Hibernate (если он включен; он не включен по умолчанию) запрашивается только после кеша L1. Это кэш «ключ-значение», данные которого сохраняются в течение нескольких сеансов.
Кэширование запросов было бы лучше всего для этого варианта использования, поскольку данные клиентов статичны и извлекаются из реляционной базы данных.
Это зависит от конкретной стратегии кеширования Hibernate, которую вы используете. На самом деле Hibernate имеет четыре разных стратегии кеширования:
READ_ONLY : объекты не меняются ни разу внутри кеша.
NONSTRICT_READ_WRITE : объекты изменяются (в конечном итоге) после обновления соответствующей записи в базе данных; это гарантирует конечную согласованность.
READ_WRITE : объекты изменяются (сразу) после обновления соответствующей записи в базе данных; это гарантирует прочную консистенцию за счет использования «мягких» замков.
TRANSACTIONAL : объекты меняются с помощью распределенных транзакций XA, обеспечивая целостность данных; это гарантирует либо полный успех, либо откат всех изменений. Однако во всех четырех случаях обновление одной записи в базе данных не приведет к аннулированию всего списка клиентов в кэше. Hibernate немного умнее этого :)
Чтобы узнать больше о том, как кэширование L2 работает в Hibernate, вы можете прочитать статью «Что такое кеш L2 Hibernate» или подробную статью Кэширование в Hibernate с помощью Redis.
источник