|
|
|
Flush-и в Hibernate и Perstistense manager
|
|||
|---|---|---|---|
|
#18+
Вопро с про работу Perstistense manager в Hibernate-е - если мы допустим, загрузили объект из базы, затем поменяли его поле, но не сохранили ещё, а потом опять грузим объект - получим то поле, которое только-что просетали, т.е грязное, получается, в некоторых случаях мы можем получить грязные данные из кэша. И противоположная ситуация - иногда Hibernated при поиске, например, при помощи Criteria API, делает flush в базу грзных данных и это может очень мешать. Когда он выбирает одно, а когда flush и как это предотвращать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.01.2006, 17:39 |
|
||
|
Flush-и в Hibernate и Perstistense manager
|
|||
|---|---|---|---|
|
#18+
Тут короткое объяснения дать очень сложно. Жизненный цикл сохраненных объектов выглядит приверно так Transient Obj->Persistent Obj-> Далее работа с сохраненным объектом ->Читаем объект->Объект попадает в кеш сессии/кеш 1-го уровня->Объект попадает в кеш 2-го уровня->Закрываем сессию Открываем новую сессию->Читаем этот же объект->на самом деле получаем объект из кеша 2-го уровня->Работаем с ним Если же мы бы не закрывали сессию, а работали с объектом после как в вашем примере то объект бы использовался вообще бы из сессионного кеша. Тут дело в том что объект считается какбы одним и на СУБД и на апп-сервере. Т.е. лучше мыслить что это один объект, состояние которого синхронизируется в определенные моменты (например при commit'е транзакции). Так что просто нужно писать код который будет верно работать именно в такой среде. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.01.2006, 16:07 |
|
||
|
Flush-и в Hibernate и Perstistense manager
|
|||
|---|---|---|---|
|
#18+
funikovyuriТут короткое объяснения дать очень сложно. Жизненный цикл сохраненных объектов выглядит приверно так Transient Obj->Persistent Obj-> Далее работа с сохраненным объектом ->Читаем объект->Объект попадает в кеш сессии/кеш 1-го уровня->Объект попадает в кеш 2-го уровня->Закрываем сессию Открываем новую сессию->Читаем этот же объект->на самом деле получаем объект из кеша 2-го уровня->Работаем с ним Если же мы бы не закрывали сессию, а работали с объектом после как в вашем примере то объект бы использовался вообще бы из сессионного кеша. Тут дело в том что объект считается какбы одним и на СУБД и на апп-сервере. Т.е. лучше мыслить что это один объект, состояние которого синхронизируется в определенные моменты (например при commit'е транзакции). Так что просто нужно писать код который будет верно работать именно в такой среде. 1) Если мы грузим один и тот же объект в рамках одной сессии, но уже успели изменить его поле, тот получим грязный объект из кэша. А вот если мы получим его как результата хитроумного поиска скажем, по criteria, то Hibernate вряд ли будет искать в кэше, иоздаётся ощущение, что Hibernate делает flush, и потом ищет по базе. Причём непонятно, по каким таблицам он делает flush - допустим, ищем объекты A, а они связаны через коллекцию с таблицей B, так он вроде как сделает flush по B ещё, или я ошибаюсь? Просто из-за такого поведения маленький поиск может вызвать много нежелательных синхронизаций и большие тормоза. 2)Если не сложно, не могли бы вы рассказать про то, чем отличается кш1 от кэш2? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.01.2006, 14:39 |
|
||
|
Flush-и в Hibernate и Perstistense manager
|
|||
|---|---|---|---|
|
#18+
Начну с конца - с рассказа про кэши... Будем считать что кэш это некоторый объект берущий на себя обязанности хранить другие объекты, помещенные в кэш клиентами, и возвращать их им по их требованию. Кроме того объекты в кэше могут устравить после чего они из него удаляются. Теперь насчет того, какие кэши используются в 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'ов. Кроме того чисто теоретически про кэши можно вообще не думать при написании кода - так как это прежде всего механизм повышения производительности. Он не должен менять логику работы. А обеспечение согласованной работы множества пользователей и приложений должно возлагаться на механизм транзакций! Вот их нужно знать и понимать прежде всего. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.01.2006, 16:17 |
|
||
|
Flush-и в Hibernate и Perstistense manager
|
|||
|---|---|---|---|
|
#18+
нифигенный пост!!! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.01.2006, 01:39 |
|
||
|
Flush-и в Hibernate и Perstistense manager
|
|||
|---|---|---|---|
|
#18+
Спасибо за объяснения. В общем, насколько я понимаю, Вы клоните к тому, что есть внутренняя кухня Hibernate-а, и в ней стоит разбираться, но писать код следует так, как если бы прослойки не было и база была бы всё время синхронизированна с Hibernate objectStorage. Используя FlushMode, удаётся заставить делать то, что нужно- меньше flush-ей при поиске, снижающих производительность, но сё равно некоторые элементы выглядят диковинно. Судя по Вашему описанию, даже при поиске при помощи query или Criteria API, hibernate сначала ищет в своих кэшах, и потом только в базе, или нет? Если так, то это получается неэффективно, т.к. база на то и база, чтобы искать максимально быстро, к тому же это приводит к увелечению размера кэша и OutOfMemoryError - к сожалению, часто стал его встречать... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.01.2006, 22:36 |
|
||
|
|

start [/forum/topic.php?fid=59&msg=33505171&tid=2150348]: |
0ms |
get settings: |
6ms |
get forum list: |
9ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
162ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
35ms |
get tp. blocked users: |
1ms |
| others: | 239ms |
| total: | 467ms |

| 0 / 0 |
