Каковы кэши первого и второго уровня в Hibernate?

245

Кто-нибудь может объяснить простыми словами, что такое кэширование первого и второго уровня в Hibernate?

suhair
источник

Ответы:

300

1.1) Кэш первого уровня

Кэш первого уровня всегда ассоциируется с объектом Session . Hibernate использует этот кеш по умолчанию. Здесь он обрабатывает одну транзакцию за другой, что означает, что не будет обрабатывать одну транзакцию много раз. В основном это уменьшает количество SQL-запросов, которые необходимо сгенерировать в рамках данной транзакции. То есть вместо обновления после каждой модификации, выполненной в транзакции, она обновляет транзакцию только в конце транзакции.

1.2) Кэш второго уровня

Кэш второго уровня всегда ассоциируется с объектом Session Factory . Во время выполнения транзакций между ними загружаются объекты на уровне фабрики сеансов, так что эти объекты будут доступны для всего приложения, а не для одного пользователя. Поскольку объекты уже загружены в кэш, всякий раз, когда объект возвращается запросом, в это время не нужно переходить к транзакции базы данных. Таким образом, работает кэш второго уровня. Здесь мы также можем использовать кеш уровня запросов.

Цитируется по адресу: http://javabeat.net/introduction-to-hibernate-caching/

Деннис С
источник
38
+1 для отображения кэша первого уровня с объектом сеанса и кэша второго уровня с объектом фабрики сеанса. мне даже не нужно было продолжать читать.
Mahes
1
Кэш 1-го уровня. в большинстве случаев это не нужно, но нет возможности избавиться от него. но вы должны думать об этом все время ..
Ses
6
@ses В большинстве случаев вам понадобится кэш 1-го уровня. В противном случае у вас возникнет очень БЕЗОПАСНАЯ проблема производительности, например, запрос N + 1, или нет кеша предварительной выборки, или запрос один раз при каждом доступе к атрибуту.
Деннис C
Обычно мы используем сессию в течение очень короткого периода времени [и очень тело рекомендует это] / недолгой сессии: мы даже не используем этот кеш в этот период. если сеанс является долгоживущим, то мы удаляем данные (например, при редактировании формы) из сеанса. Кажется, это необходимо только для одного сценария, когда мы пытаемся использовать query-session-api при создании некоторого сложного запроса после запроса для долгоживущего сеанса.
ses
1
@DennisCheung: ссылка мертва. Пожалуйста, обновите с javabeat.net/introduction-to-hibernate-caching
NewUser
118

В блоге Streamline Logic есть довольно хорошее объяснение кеширования первого уровня .

По сути, кэширование первого уровня происходит отдельно для каждого сеанса, тогда как кэширование второго уровня может совместно использоваться несколькими сеансами.

lomaxx
источник
20
вот такие простые слова, я не знаю, почему им так трудно это объяснить
BlackTigerX
хе-хе ... да я действительно не знаю, как я мог бы стать намного проще :)
lomaxx
2
это на самом деле более понятным для меня. во-первых, для каждой сессии, а во-вторых, для нескольких сессий, мне просто помнить. не можем ли мы проголосовать дважды? : D
черный сэнсэй
1
нет примера, зачем нужен кэш 1-го уровня. как по мне в большинстве случаев это вообще не нужно. но вы должны думать об этом и о сессии все время.
ses
Прошло 11 лет с тех пор, как этот ответ, и, к сожалению, ссылка не существует сейчас. Но я нашел его содержимое на его архивной веб-странице: web.archive.org/web/20081207044228/http://…
Golu
105

Вот некоторые основные объяснения кибер-кэша ...

Кэш первого уровня связан с объектом «сеанс». Область действия объектов кэша имеет сессию. Как только сессия закрыта, кэшированные объекты исчезают навсегда. Кэш первого уровня включен по умолчанию, и вы не можете его отключить. Когда мы запрашиваем объект в первый раз, он извлекается из базы данных и сохраняется в кэше первого уровня, связанном с сеансом гибернации. Если мы снова запросим тот же объект с тем же объектом сеанса, он будет загружен из кэша, и никакой SQL-запрос не будет выполнен. Загруженный объект может быть удален из сеанса с использованием evict()метода. Следующая загрузка этой сущности снова вызовет базу данных, если она была удалена с помощью evict()метода. Весь кэш сеанса можно удалить с помощью clear()метода. Это удалит все сущности, хранящиеся в кеше.

Кэш второго уровня отличается от кэша первого уровня, который доступен для глобального использования в области фабрики сеансов. Кэш второго уровня создается в области фабрики сеансов и доступен для использования во всех сеансах, которые создаются с использованием этой конкретной фабрики сеансов. Это также означает, что после закрытия фабрики сеансов весь кэш, связанный с ним, умирает, а менеджер кеша также закрывается. Всякий раз, когда сеанс гибернации пытается загрузить объект, самое первое место, где он ищет кэшированную копию объекта в кэше первого уровня (связан с конкретным сеансом гибернации). Если кэшированная копия объекта присутствует в кэше первого уровня, она возвращается как результат метода загрузки. Если в кэше первого уровня нет кэшированной сущности, то для кэшированной сущности ищется кэш второго уровня. Если кэш второго уровня имеет кешированную сущность, он возвращается как результат метода load. Но, перед возвратом объекта он также сохраняется в кэше первого уровня, так что при следующем вызове метода загрузки для объекта объект будет возвращен из самого кэша первого уровня, и больше не потребуется возвращаться в кэш второго уровня. Если объект не найден в кэше первого уровня и кэше второго уровня, то выполняется запрос к базе данных, и объект сохраняется на обоих уровнях кэша, а затем возвращается как ответload() метод.

Creditto
источник
2
Отличное объяснение! Если бы вы могли нарисовать несколько диаграмм последовательности, это было бы здорово !!!
Аделин
подробное и приятное объяснение
ManishS
1
Если вы хотите пересмотреть то, что вы уже знаете, то два приведенных выше ответа Денниса С и Iomaxx великолепны, очень кратки и легко запоминаются. Однако, если вы ищете объяснение разницы, когда вы еще этого не знаете, этот ответ будет намного лучше!
Студенческая душа
Отличное объяснение !!
blu3
17

Это очень распространенный вопрос, поэтому этот ответ основан на статье, которую я написал в своем блоге.

Кэш первого уровня

Hibernate пытается отложить сброс постоянства контекста до последнего возможного момента. Как я объяснил в этой статье , эта стратегия традиционно известна как транзакционная обратная запись.

Перезапись в большей степени связана с сбросом Hibernate, а не с какой-либо логической или физической транзакцией. Во время транзакции сброс может происходить несколько раз.

введите описание изображения здесь

Сброшенные изменения видны только для текущей транзакции базы данных. Пока текущая транзакция не будет зафиксирована, другие параллельные транзакции не видят изменений.

Благодаря кешу первого уровня, Hibernate может выполнять несколько оптимизаций:

Кэш второго уровня

Правильное решение для кэширования должно охватывать несколько сеансов Hibernate, и именно поэтому Hibernate также поддерживает дополнительный кэш второго уровня.

Кэш второго уровня связан с жизненным циклом SessionFactory, поэтому он уничтожается только при SessionFactoryзакрытии (как правило, когда приложение закрывается). Кэш второго уровня в основном ориентирован на сущности, хотя также поддерживает дополнительное решение для кэширования запросов.

Для более подробной информации, проверьте эту статью .

Влад Михалча
источник
3

по умолчанию NHibernate использует кэширование первого уровня, основанное на объекте сеанса. но если вы работаете в многосерверной среде, то кэш первого уровня может не очень масштабироваться вместе с некоторыми проблемами с производительностью. это происходит из-за того, что приходится совершать очень частые поездки в базу данных, поскольку данные распределяются по нескольким серверам. другими словами, NHibernate предоставляет базовую, не очень сложную внутрипроцессную кэш-память L1 из коробки. Однако он не предоставляет функций, которые решение для кэширования должно оказывать заметное влияние на производительность приложения.

поэтому все эти проблемы связаны с использованием кэша L2, который связан с объектами фабрики сеансов. это сокращает длительные поездки в базу данных, что в конечном итоге увеличивает время отклика приложения.

Ravian
источник
1

Кэш первого уровня

Объект Session содержит данные кэша первого уровня. Это включено по умолчанию. Данные кэша первого уровня не будут доступны всему приложению. Приложение может использовать много объектов сеанса.

Кэш второго уровня

Объект SessionFactory содержит данные кэша второго уровня. Данные, хранящиеся в кэше второго уровня, будут доступны всему приложению. Но мы должны включить это явно.

Неудачник
источник
-4

В кэше второго уровня файлы домена hbm могут иметь изменяемый ключ и значение false. Например, в этом классе предметной области некоторая продолжительность дня остается постоянной как универсальная истина. Таким образом, он может быть помечен как неизменный во всем приложении.

Пракаш Баяс
источник