Изменение закэшированных объектов
От: Andrey Lastochkin Россия  
Дата: 15.06.07 07:06
Оценка:
Добрый день, друзья.

У нас в приложении есть кэш. Там хранятся базовые коллекции объектов — пользователи, основные справочники.

При получении пользователя, например User.GetById(id), возвращается объект из кэша.
Т.е. в приложении существует только один экземпляр объекта. В этом случае, любой модуль может изменить атрибуты этого экземпляра и тогда это изменение затронет всё остальное, что не есть gut.

Какие есть варианты решения этой проблемы? (каждый раз при получении клонировать объект не хочется)

Андрей.
Re: Изменение закэшированных объектов
От: GlebZ Россия  
Дата: 15.06.07 07:50
Оценка:
Здравствуйте, Andrey Lastochkin, Вы писали:

AL>Какие есть варианты решения этой проблемы? (каждый раз при получении клонировать объект не хочется)

Объект у тебя становится членом изолированной транзакции, и тебе ее копировать не хочется? Мало того, нужно просматривать вопрос всех ACID свойствах транзакции с учетом кэширования.
Re: Изменение закэшированных объектов
От: Аноним  
Дата: 15.06.07 09:46
Оценка:
AL>Какие есть варианты решения этой проблемы? (каждый раз при получении клонировать объект не хочется)

Так как после изменения старый объект в кэше очевидно невалиден, то самый правильный путь, по моему, это удалить старый объект из кэша и при следующем обращении за этим объектом кэш должен заново перечитать объект из базы. Клиенты, которые получили объект до этого, будут держать ссылку на старый объект. Можно выкидывать из кэша и объекты/коллекции, на которые может повлиять данное изменение.
Re[2]: Изменение закэшированных объектов
От: Andrey Lastochkin Россия  
Дата: 15.06.07 11:35
Оценка:
AL>>Какие есть варианты решения этой проблемы? (каждый раз при получении клонировать объект не хочется)
GZ>Объект у тебя становится членом изолированной транзакции, и тебе ее копировать не хочется? Мало того, нужно просматривать вопрос всех ACID свойствах транзакции с учетом кэширования.

А вот зависит от того, для чего объект: для чтения или для изменения. По идее, если он нужен только для чтения — его и клонировать не надо.
А если ты хочешь его модифицировать и сохранить в базу — тогда его надо клонировать, изменять, сохранять в базу, коммитить и только потом обновлять к кэше.

Почему я не хочу клонировать: вот например, мне нужно отобразить список документов и их авторов (ФИО). Получается на каждую строку (на каждый документ), надо наклонировать еще столько же авторов, только для того чтобы прочитать и отобразить их имя.

Андрей.
Re[3]: Изменение закэшированных объектов
От: GlebZ Россия  
Дата: 15.06.07 11:52
Оценка:
Здравствуйте, Andrey Lastochkin, Вы писали:

AL>>>Какие есть варианты решения этой проблемы? (каждый раз при получении клонировать объект не хочется)

GZ>>Объект у тебя становится членом изолированной транзакции, и тебе ее копировать не хочется? Мало того, нужно просматривать вопрос всех ACID свойствах транзакции с учетом кэширования.

AL>А вот зависит от того, для чего объект: для чтения или для изменения. По идее, если он нужен только для чтения — его и клонировать не надо.

AL>А если ты хочешь его модифицировать и сохранить в базу — тогда его надо клонировать, изменять, сохранять в базу, коммитить и только потом обновлять к кэше.

AL>Почему я не хочу клонировать: вот например, мне нужно отобразить список документов и их авторов (ФИО). Получается на каждую строку (на каждый документ), надо наклонировать еще столько же авторов, только для того чтобы прочитать и отобразить их имя.

Скажу так. Приложение должно быть специфично-требовательное к ресурсам, чтобы пожертвовать простотой ради некоторой избыточности работы с памятью. Способов обеспечить транзакционность море. Один из них уже описали. Тут есть зависимость от того что ты пишешь(об этом я только могу догадываться). Главное, чтобы голова при этом присутсвовала.
Можешь посмотреть этот флейм: здесь
Автор: shev
Дата: 26.01.06
Re: Изменение закэшированных объектов
От: Нахлобуч Великобритания https://hglabhq.com
Дата: 15.06.07 12:51
Оценка: 1 (1)
Здравствуйте, Andrey Lastochkin, Вы писали:

AL>Какие есть варианты решения этой проблемы? (каждый раз при получении клонировать объект не хочется)


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

В NH реализовано двухуровневое кэширование. Кэш первого уровня -- это не совсем кэш, а Identity Map и Unit of Work одновременно (по поводу, что это такое см. флейм, на который GlebZ дал ссылку). А вот на втором уровне все честно: Application-Wide-кэш, хранящий все бизнес-объекты, но в "разобранном" виде: грубо говоря, словарь типа "свойство"-"значение".
При выполнении запроса типа "select ... from ... where id = ?" первым делом просматривается текущая Identity Map и, если объект там уже есть, то возвращается ссылка на него и запрос в БД не уходит. Если же его там нет, то проверяется кэш второго уровня; если там есть разобранное представление требуемого объекта, то он собирается обратно и возвращается вызывающему коду. В противном случае выполняется запрос, возвращается объект, разбирается по косточкам и кладется в кэш второго уровня, попадает в Identity Map и наконец возвращается прикладному коду.

Смысл такой механики хранения объектов в кэше второго уровня в том, что два разных Unit of Work'а могут свободно модифицировать свойства одного и того же (с логической точки зрения) объекта, не заботясь о межпоточной синхронизации и не опасаясь нарваться на несогласованные данные в пределах своего UoW. Другое дело, что если оба UoW попытаются записать данные в БД, но это слегка другая история.
HgLab: Mercurial Server and Repository Management for Windows
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.