powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Flush-и в Hibernate и Perstistense manager
6 сообщений из 6, страница 1 из 1
Flush-и в Hibernate и Perstistense manager
    #33500542
Urt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вопро с про работу Perstistense manager в Hibernate-е - если мы допустим, загрузили объект из базы, затем поменяли его поле, но не сохранили ещё, а потом опять грузим объект - получим то поле, которое только-что просетали, т.е грязное, получается, в некоторых случаях мы можем получить грязные данные из кэша. И противоположная ситуация - иногда Hibernated при поиске, например, при помощи Criteria API, делает flush в базу грзных данных и это может очень мешать. Когда он выбирает одно, а когда flush и как это предотвращать?
...
Рейтинг: 0 / 0
Flush-и в Hibernate и Perstistense manager
    #33502890
funikovyuri
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тут короткое объяснения дать очень сложно. Жизненный цикл сохраненных объектов выглядит приверно так

Transient Obj->Persistent Obj->
Далее работа с сохраненным объектом
->Читаем объект->Объект попадает в кеш сессии/кеш 1-го уровня->Объект попадает в кеш 2-го уровня->Закрываем сессию

Открываем новую сессию->Читаем этот же объект->на самом деле получаем объект из кеша 2-го уровня->Работаем с ним

Если же мы бы не закрывали сессию, а работали с объектом после как в вашем примере то объект бы использовался вообще бы из сессионного кеша.

Тут дело в том что объект считается какбы одним и на СУБД и на апп-сервере. Т.е. лучше мыслить что это один объект, состояние которого синхронизируется в определенные моменты (например при commit'е транзакции). Так что просто нужно писать код который будет верно работать именно в такой среде.
...
Рейтинг: 0 / 0
Flush-и в Hibernate и Perstistense manager
    #33505171
Urt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
funikovyuriТут короткое объяснения дать очень сложно. Жизненный цикл сохраненных объектов выглядит приверно так

Transient Obj->Persistent Obj->
Далее работа с сохраненным объектом
->Читаем объект->Объект попадает в кеш сессии/кеш 1-го уровня->Объект попадает в кеш 2-го уровня->Закрываем сессию

Открываем новую сессию->Читаем этот же объект->на самом деле получаем объект из кеша 2-го уровня->Работаем с ним

Если же мы бы не закрывали сессию, а работали с объектом после как в вашем примере то объект бы использовался вообще бы из сессионного кеша.

Тут дело в том что объект считается какбы одним и на СУБД и на апп-сервере. Т.е. лучше мыслить что это один объект, состояние которого синхронизируется в определенные моменты (например при commit'е транзакции). Так что просто нужно писать код который будет верно работать именно в такой среде.

1) Если мы грузим один и тот же объект в рамках одной сессии, но уже успели изменить его поле, тот получим грязный объект из кэша. А вот если мы получим его как результата хитроумного поиска скажем, по criteria, то Hibernate вряд ли будет искать в кэше, иоздаётся ощущение, что Hibernate делает flush, и потом ищет по базе. Причём непонятно, по каким таблицам он делает flush - допустим, ищем объекты A, а они связаны через коллекцию с таблицей B, так он вроде как сделает flush по B ещё, или я ошибаюсь? Просто из-за такого поведения маленький поиск может вызвать много нежелательных синхронизаций и большие тормоза.
2)Если не сложно, не могли бы вы рассказать про то, чем отличается кш1 от кэш2?
...
Рейтинг: 0 / 0
Flush-и в Hibernate и Perstistense manager
    #33505488
funikovyuri
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Начну с конца - с рассказа про кэши...

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

Теперь насчет того, какие кэши используются в Hibernate.
Прежде всего все полученные из БД объекты попадают в сессионный кэш (или кэш 1го уровня) где пребывают до конца текущей транзакции. Сессионный кэш еще называется транзакционным - так как в нем кэшируются данные одной транзакции . Таким образом, если в одной транзакции один и тот же объект читается 2 раза второй раз он будет взят из кэша. Также должно быть ясно, что если этот объект был изменен в этой транзакции между операциями чтения, то вторая вернет именно этот измененный, еще не закомиченный объект. Если это кому-то кажется странным, то советую провести аналогию с подобными действиями на стороне БД - все в точности так же.

Кроме сессионного можно использовать и так называемый кэш второго уровня (который бывает уровня процесса или уровня jvm или кластерным). В hibernate реализация этого кеша может быть подключена/заменена в зависимости от потребностей пользователя. Для этого кэша важнейшим параметром является т.н. cache concurrency strategy . Она бывает transactional, read-write, nonstrict-read-write или read-only и задается в секции <cache> файла hibernate.cfg.xml. За подробностями см. http://www.hibernate.org/hib_docs/v3/reference/en/html/performance.html#performance-cache так как заниматься просто переводом документации я не хочу.

Данные из кэша 1-го уровня могут попадать в кэши второго и наоборот. Политика их взаимодействия определяется параметром CacheMode. Тут прежде всего нужно понимать что при запросе объекта Hibernate прежде всего ищет его в сессионном кэше, затем в кэше 2-го уровня и лишь затем в БД.

Также нужно помнить что при выполнении
save(), update() или saveOrUpdate(), также load(), get(), list(), iterate() or scroll() объект будет помещен в кэш 1-го уровня. Еще более важно, что после выполнения flush() состояние ВСЕХ объектов в сессионном кэше будет синхронизированно с БД. Поэтому если синхронизировать состояние какихто объектов в кэше не нужно можно им управлять.
Проверить, а также управлять содержимым кэша можно с помощью session.evict()/session.contains() (соответсвенно sessionFactory.evict()/sessionFactory.contains() для кэша 2-го уровня). Есть даже возможность полностью отчистить кэш - session.clear().

Кроме этих двух кэшей, существует еще и так называемый query cache. используется для кэширования результатов выполнения запросов выполняющихся часто и с одними и теми же параметрами. обычно не используется. см. http://www.hibernate.org/hib_docs/v3/reference/en/html/performance.html#performance-cache 19.4. The Query Cache


Теперь по поводу первого вопроса.

Как я уже писал процесс синхронизации состояний объектов в кэшах называется flush и может быть выполнен вручную с помощью вызова одноименного метода сессии. кроме того нужно помнить что этот же процесс будет запущен неявно в следующие моменты
* перед выполнением какого либо запроса
* во время выполнения commit'а
см. http://www.hibernate.org/hib_docs/v3/reference/en/html/objectstate.html#objectstate-flushing
Можно сделать запуски flush еще менее частыми регулируя параметр FlushMode. Например, только во время commit'ов.

Кроме того чисто теоретически про кэши можно вообще не думать при написании кода - так как это прежде всего механизм повышения производительности. Он не должен менять логику работы. А обеспечение согласованной работы множества пользователей и приложений должно возлагаться на механизм транзакций! Вот их нужно знать и понимать прежде всего.
...
Рейтинг: 0 / 0
Flush-и в Hibernate и Perstistense manager
    #33506341
Exppp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
нифигенный пост!!!
...
Рейтинг: 0 / 0
Flush-и в Hibernate и Perstistense manager
    #33508639
Urt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо за объяснения. В общем, насколько я понимаю, Вы клоните к тому, что есть внутренняя кухня Hibernate-а, и в ней стоит разбираться, но писать код следует так, как если бы прослойки не было и база была бы всё время синхронизированна с Hibernate objectStorage. Используя FlushMode, удаётся заставить делать то, что нужно- меньше flush-ей при поиске, снижающих производительность, но сё равно некоторые элементы выглядят диковинно.
Судя по Вашему описанию, даже при поиске при помощи query или Criteria API, hibernate сначала ищет в своих кэшах, и потом только в базе, или нет? Если так, то это получается неэффективно, т.к. база на то и база, чтобы искать максимально быстро, к тому же это приводит к увелечению размера кэша и OutOfMemoryError - к сожалению, часто стал его встречать...
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Flush-и в Hibernate и Perstistense manager
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]