Кэшированныезначения 1с для чего
Если до работы в 1С:Предприятии 8.3 Вы пользовались предыдущими версиями программы (8.2, 8.1, 8.0, не говоря уже о 7.7), то не могли не заметить, что при переходе на версию платформы 8.3 размер информационной базы (ИБ) значительно возрос.
Во-первых, уже просто пустая база занимает места столько, как будто в ней уже очень много данных. Во-вторых, в процессе использования программы размер базы растёт значительно быстрее.
Во многом увеличение размера базы 1С:Предприятие 8.3 в сравнении с предыдущими версиями обусловлено переходом на "управляемые формы", но мы это здесь обсуждать не будем, а рассмотрим некоторые способы сокращения размера базы, которые могут быть полезны обычным пользователям программы.
К сведению программистов, сисадминов и прочих IT-специалистов
Статья предназначается в помощь обычным пользователям, поэтому если Вы знаете какой-то сложный метод, позволяющий уменьшить базу, но который не сможет применить рядовой пользователь 1С, просьба воздержаться от подобных предложений.
Помним, что значительная часть пользователей 1С:Предприятие не разбирается (и не обязана разбираться) в технических особенностях устройства программы, а также функционирования операционной системы и компьютера в целом.
Замечание для обычных пользователей
Поскольку для 1С:Предприятие есть много разных конфигураций, а проблема размера базы одна на всех, то приводить конкретные примеры (если они касаются конфигурации, а не платформы) мы будем для "Бухгалтерии предприятия".
К другим конфигурациям всё сказанное применимо "по аналогии".
Итак, посмотрим некоторые способы сокращения размера базы 1С, а также как сделать так, чтобы база не увеличивалась чрезмерно.
Отказ от ответственности
Все операции, предлагаемые в статье, Вы выполняете на свой страх и риск. Мы лишь приводим информацию в образовательных целях.
Если у Вас есть сомнения - обратитесь к специалисту по 1С Вашей компании.
Не загружайте в базу КЛАДР/ФИАС полностью!
Довольно часто происходит следующее: пользователь берёт и загружает все регионы адресного классификатора. Происходит это обычно по трём основным причинам:
- Пользователь новичок и "не подумал", зачем ему все регионы в базе, то есть загрузил "на всякий случай".
- "Не знал", что можно загрузить только часть справочника (маловероятно, но и так бывает).
- "Надоело" время от времени добавлять новые регионы, когда они реально требуются, но при этом не загружены (два-три-четыре раза добавил новые регионы, а потом надоело и решил загрузить сразу весь справочник, чтобы больше на это не отвлекаться).
В результате в базу 1С попадает очень много лишних данных, а размер самой ИБ возрастает очень существенно. Давайте посмотрим, на сколько именно:
- версия 8.2: 1500 Мб ( + 1 Гб к пустой базе);
- версия 8.3: 3000 Мб ( + 2,5 Гб к пустой базе);
Таким образом, не стоит загружать те регионы, которые реально не используются. Это не просто лишние данные, но они также попадают и в резервные копии (что увеличивает размер бэкапа, а также время его создания).
Если Вы уже загрузили лишнее, то удалите ненужные регионы и размер базы уменьшится.
Как уменьшить старую базу 1С:Предприятие
Это решение подходит для тех случаев, когда база существует давно (годы) и документов в ней накопилось очень много. В таком случае можно избавиться от части документов, выполнив специальную операцию, которая в 1С называется " свёртка информационной базы ".
(!) Обратите внимание, что эта операция не может быть отменена (кроме как восстановлением из резервной копии), поэтому подумайте перед её выполнением (и сделайте копию базы).
Принцип свёртки заключается в том, что в базе есть старые документы, которые на 100% никогда уже не понадобятся. От них можно избавиться, урезав базу до определённой даты (до какой - смотрите сами).
Данная операция выполняется из раздела Администрирование. Где конкретно находится этот пункт, зависит от точной версии программы и конфигурации (в любом случае есть быстрый поиск по меню). Ниже приведён скриншот для одной из версий 1С:Бухгалтерии 8.3.
В процессе выполнения свёртки 1С проверит все документы от начала базы и до указанной Вами даты свёртки, после чего на основе этих документов сформирует "остатки", а сами данные удаляет.
В результате база не пострадает, итого не "поплывут", но документов станет меньше (иногда значительно). Вот так и будет сокращена база.
При выполнении свёртки следуйте инструкциям 1С. Если же Вы не уверены, что сможете (и хотите) делать это самостоятельно, обратитесь к соответствующему IT-специалисту Вашей компании.
Замечание: вообще так всегда и следует делать, поскольку техническое обслуживание базы - не дело рядового пользователя. Тем не менее, знание подобных операций часто бывает очень полезно владельцам мелких ИП/ООО.
Очистите журнал регистрации
Когда Вы что-то делаете в программе, она не просто выполняет нужные Вам операции, но и ведёт специальный журнал: кто, когда и что делал. Этот лог называется журналом регистрации и в него часто попадает слишком много информации, а сам журнал может занимать очень много места, значительно увеличивая размер базы 1С.
Представьте себе, что все Ваши действия в 1С записываются годами! Это очень много данных.
Конечно, иногда информация из журнала регистрации может быть очень полезной. Но для большинства пользователей эти данные не несут никакой полезной нагрузки и могут быть без последствий удалены. Если Вы сомневаетесь в целесообразности данной операции - проконсультируйтесь с 1С-программистом или системным администратором Вашей компании!
Журнал регистрации можно очистить через Конфигуратор. Принцип показан на скриншоте ниже.
Чтобы журнал в дальнейшем не забился снова, настройте сохранение только критичных для Вас данных.
Если у Вас файловая база 1С, то есть все данные хранятся в папке на диске, то очистить журнал можно удалением подпапки 1Cv8Log.
Помните, что очистку журнала нельзя отменить, поэтому выполните резервное копирование папки базы перед очисткой.
Уменьшаем размер резервной копии базы
Это тоже важно, потому что при регулярном резервном копировании бэкапы могут занимать много места. В случае файловой базы просто сожмите резервную копию архиватором - сжатие может быть очень значительным.
Кстати, это доказывает, что база 1С состоит в основном из пустоты.
Есть ли вообще смысл уменьшать размер базы?
Чем меньше база, тем быстрее работает программа. А поскольку современные версии 1С:Предприятие 8.3 весьма "тормозные", то ускорить их не помешает.
Заметите ли Вы эффект от уменьшения размера базы? Это зависит от каждого случая индивидуально. В любом случае чем меньше места занимает ИБ, тем:
- быстрее выполняется регулярное резервное копирование;
- меньше места занимают резервные копии;
- сама база занимает меньше места;
- программа может работать быстрее (заранее сложно сказать);
Дополнительная информация по теме
На нашем сайте приведено также сравнение размеров базы для версии 1С:Предприятие 8.3 и 8.2 для конфигурации "Бухгалтерия предприятия". Вы можете на примере сравнить, как изменился размер базы при переходе на версию 8.3.
Также по указанной ссылке находится более подробное описание рассмотренных выше некоторых способов сжатия базы.
Поделитесь своим опытом
Знаете другие способы сжатия базы или просто имеете опыт уменьшения размера базы 1С:Предприятия? Поделитесь своим опытом в комментариях - это поможет другим пользователям лучше понять программу.
В своей первой статье Использование программных перечислений, ч.1: строковые константы я рассказал о способе, который избавит от неприятностей, связанных с сравнением в коде на строку. Здесь на базе этого-же приема рассмотрена задача по оптимизации загрузки данных из внешнего источника. Расскажу о случае, который неоднократно наблюдал в разных его ипостасях. Стоит задача по загрузке данных в БД из внешнего файла, заказчик предоставил пару примеров, программист успешно все реализовал\протестил, сдал работу.. И тут через месяц заказчик грузит файл раз эдак в 50 превышающий пример.. Все не просто тупит, а зависает на
2 часа. Заказчик недоволен. После работ по оптимизации время загрузки снизилось с 2 часов до 30 минут (из которых только 5 это синхронизация, а все остальное - запись данных в базу).. В чем же была ошибка? При синхронизации данных не использовалось кэширование, и поиск ссылок по одним и тем же ключевым полям выполнялся многократно. После того как был добавлен кэш все залетало.
Началась оптимизация с того, что я добавил глобальную переменную типа "Структура", которая и выполняет роль кэша:
Расскажу далее о нескольких универсальных методах, которые полезно применять в подобных случаях.
Синхронизация входящих данных с данными базы - один из самых болезненных этапов при написании любых обменов / загрузок. Особенно, если не кэшировать результаты поиска. Хочу погрузить читателя в один душераздирающий пример:
Теперь представьте, что в ТаблицаДанныеФайла 1000 строк, а физ. лиц- всего 10. Т.е. запрос в цикле по поиску физ. лица выполняется лишних 990 раз. Есть два решения:
- самый быстрый - это сделать пред-выборку по физ.лицам и организациям, передав туда массивы поисковых реквизитов. В цикле по основной таблице поиск ссылки выполнять уже по заранее полученным выборкам, где хранится соответствие <ПоисковыйРеквизит> - <Найденная или пустая ссылка> (этот способ рассмотрен ниже, в главе 2)
- чуть менее быстрый, но более читабельный вариант - который я выбираю из-за простоты и скорости реализации - это использовать кэширующий поиск. Все входящие данные загоняем в кэш, и перед тем как выполнить запрос проверяем - был ли он выполнен ранее с параметром конкретного поискового реквизита. Таким образом каждая ссылка ищется только один раз, а впоследствии получается из кэша.
Уже эта доработка дала существенные результаты, о которых я сказал выше. Такой подход экономит время поиска, и при том выглядит читабельно. В отличие от более "быстрого" способа с пред-выборками - в кавычках быстрого, поскольку временной выигрыш пропорционален разреженности значений поиска. Если у нас 1000 строк, в которых два контрагента - быстрее будет работать кэширующий поиск. Если на 1000 строк есть 200 уникальных контрагентов - то быстрее пред-выборка, но тут надо учитывать нагрузку на память. Окончательный вариант подбирается в процессе оптимизации, если есть достаточно примеров - оба показывают хорошее время, я обычно работаю именно с вторым способом.
Но это еще не все:) Представьте что в цикле далее идут такие строки:
Запрос в цикле все заметили. Не буду говорить что уж организаций-то на 1000 строк явно немного. Например их в принципе в базе две. Так зачем 998 раз повторять один и тот-же запрос? Оптимизировать этот момент можно используя такую функцию:
На выходе получим код:
2. Выборка из результата запроса, и метод "НайтиСледующий()"В предыдущей главе я упоминал что поиск по заранее подготовленному массиву данных зачастую эффективнее, чем кэширующий поиск. Я намеренно пока не употребляю термин "Выборка", поскольку здесь есть такие варианты:
2.1 Загнать саму исходную таблицу в запрос (колонки должны быть заранее протипизированы), в запросе левым соединением по синхронизирующим полям получать ссылки из нужных таблиц. Выглядит это так:
Этот способ плох тем, что исходная таблица может быть очень объемной - кстати, при написании любых загрузок следует исходить именно из этого принципа - что исходный пример может быть увеличен в десятки раз. Если загружается некий excell на 100000 позиций, то время при таком подходе тратится на сбор данных в промежуточную таблицу значений ТаблицаДанныеФайла - которая сама по себе занимает порядком памяти, а также на ее помещение в временную таблицу запроса. Использование любого подхода с пред-выборкой связано с риском утечек памяти. Я однажды видел загрузку прайс-листа, реализованную так, что людям приходилось по ночам перезагружать сервер 1С. Вывод: лучше 10 быстрых подзапросов, чем один но объемный.
2.2 Более щадящий память метод связан с использованием метода выборки "НайтиСледующий", и в общем-то это глава как-раз о нем) Поскольку он не всегда применим, а при загрузке данных из объемного внешнего источника - по моему опыту не применим вовсе. Поясню что имею в виду, на примере:
Использование метода выборки "НайтиСледующий()", с сбросом выборкиЭтот способ сэкономит память, но не время поиска. По опыту - суммарное выполнение методов "НайтиСледующий" может занимать объем времени, в десятки раз превышающий затраты на сам запрос! Дело здесь в том, что каждый раз после выполнения удачного поиска используется сброс выборки, и каждый раз поиск начинается с начала - с самой первой строки. Отсюда следует что при больших объемах это использовать не стоит. Предупреждая вопрос "а если выгрузить результаты в таблицу значений, и искать по ней" - то же самое. ТЗ можно проиндексировать при больших объемах, но стабильное хорошее время это не обеспечит: во-первых таблица будет занимать память, во вторых - поиск без индекса будет затратен при большой выборке данных, а при малой выборке будут затраты на само построение индекса.
При всем при том - метод НайтиСледующий() очень хорош, когда необходимо связать данные двух запросов. Ведь если обеспечить одинаковый порядок поисковых реквизитов - то можно отказаться от сброса выборки, и каждый новый поиск будет выполнятся с текущего положения курсора - а это хороший выигрыш в скорости, по сравнению с составным поиском по таблице значений, например. Его я использую при написании сложных отчетов - когда нет возможности получить все данные за один заход. Тогда чтобы декомпозировать код, и обеспечить хорошую скорость отчета можно получить такой пример:
Использование метода выборки "НайтиСледующий()", без сброса выборкиИ тут возникает такой вопрос. Получается - если в 2.2 отсортировать выходные поля таким образом, чтобы синхронизация была одинакова - то можно пользоваться поиском по выборке? Да, но выполняется несколько поисков, и использовать сортировку исходного набора можно только для одного из них:
А если выборка сбрасывается хоть раз - ее использование уже неэффективно.
Хочу добавить кое-что о сортировке таблицы значений по колонкам с ссылочными значениями. Фраза с ИТС ". рекомендуется. в остальных случаях – сортировать «по ссылке», а не по представлению. Для этого в методе Сортировать следует использовать объект СравнениеЗначений " (
Демонстрация поиска с использованием отсортированной таблицы значенийВ заключение этой главы скажу что наиболее оптимально при загрузке данных из внешних источников использовать именно кэширующий поиск. Он может породить множество подзапросов, и в каких-то случаях быть менее эффективным чем поиск по пред-выборке - но чаще всего это оправдано за счет экономии памяти, а также более читабельного кода. Кроме того - для поиска по пред-выборке необходим некий пул данных, т.е. сначала обходим Excell, загоняем данные в таблицу значений (!память!) а далее используем эту таблицу для получения пулов поисковых реквизитов. Использование кэширующего поиска позволяет выполнить синхронизацию непосредственно из самой выборки по источнику (например при обходе результата ADO-запроса).
Кэшировать можно и нужно не только данные для синхронизации, но некоторые константные вспомогательные переменные. Благодаря функции "Счета<Префикс по плану счетов>()" новая переменная добавляется простым редактированием строки кодов счетов:
- Это гораздо быстрее, чем писать ПланыСчетов.Управленческий.<ИмяПредопределенногоСчета>
- Имя предопределенного элемента еще надо узнать - я не встречал таких гуру, которые по коду счета помнят идентификатор предопределенного элемента. Обычно в голове сидит именно код счета, а идентификатор узнается через предопределенный список элементов плана счетов, т.е. туда надо провалиться, найти код счета, скопировать имя. - долго, добавить код в строку гораздо быстрее.
- Счет может и не быть предопределенным. В таких случаях часто используют конструкцию "НайтиПоКоду", причем вызывают ее десять раз подряд, при чем не гнушаются циклом. Мрак:)
Довольно часто по счету группе необходимо получить список подчиненных ему субсчетов, чтобы обращаться к ним в коде.
Также бывает необходимо получить массив субсчетов, чтобы передать их в параметр запроса, или проверить - является ли счет субсчетом
В той самой ситуации, о которой я рассказал в начале статьи, в некоторой части кода требовалось выполнять действия в зависимости от того использовался ли на счете некий вид субконто. Что сделал программист? Получил объект счета, и проверял его табличную часть "ВидыСубконто". Что сделал я - да то же самое, только без получения объекта, и с использованием кэшируемого поиска:
Транзакции: правила использования
Область применения: управляемое приложение, мобильное приложение, обычное приложение.
Транзакции применяются для целостного изменения связанных данных, т.е. все действия с базой данных, выполняемые в рамках транзакции или выполняются целиком, или целиком откатываются.
1. Использование транзакций в 1С:Предприятии обладает рядом особенностей:
не поддерживаются вложенные транзакции (см. подробнее Вложенность транзакций); при возникновении исключения в общем случае транзакция не может быть зафиксирована – при этом не важно, было ли это исключение обработано или нет (см. подробнее Ошибки базы данных и транзакции, Особенности работы объектов при отмене транзакции); транзакция может быть инициирована явно в прикладном коде при использовании метода НачатьТранзакцию . Так же платформа 1С:Предприятие неявным образом начинает транзакцию при любой записи в базу данных (см. подробнее Документация платформы. Механизм транзакций);Эти особенности накладывают ряд требований к написанию кода с использованием транзакций. Несоблюдение этих требований может приводить к возникновению ошибок вида «В этой транзакции уже происходили ошибки», которые может быть крайне сложно воспроизвести и отладить.
1.1. Поскольку исключение не отменяет транзакцию сразу, но запрещает успешное завершение транзакции, то все вызовы НачатьТранзакцию с одной стороны и ЗафиксироватьТранзакцию или ОтменитьТранзакцию с другой стороны должны быть парными.
1.2. Начало транзакции и ее фиксация (отмена) должны происходить в контексте одного метода
Попытка
. // чтение или запись данных
ДокументОбъект.Записать()
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
. // дополнительные действия по обработке исключения
КонецПопытки;
Попытка
. // чтение или запись данных
ДокументОбъект.Записать()
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
. // дополнительные действия по обработке исключения
КонецПопытки;
1.3. При использовании транзакций необходимо предусмотреть обработку исключений, придерживаясь следующих правил:
метод НачатьТранзакцию должен быть за пределами блока Попытка-Исключение непосредственно перед оператором Попытка ; все действия, выполняемые после вызова метода НачатьТранзакцию , должны находиться в одном блоке Попытка, в том числе чтение, блокировка и обработка данных; метод ЗафиксироватьТранзакцию должен идти последним в блоке Попытка перед оператором Исключение , чтобы гарантировать, что после ЗафиксироватьТранзакцию не возникнет исключение; необходимо предусмотреть обработку исключений – в блоке Исключение нужно сначала вызвать метод ОтменитьТранзакцию , а затем выполнять другие действия, если они требуются; при использовании вложенных транзакций (см. п. 1.4) в конце блока Исключение рекомендуется добавить оператор ВызватьИсключение . В противном случае исключение не будет передано выше по стеку вызовов, там не сработает обработка исключения, внешняя транзакция не будет явным образом отменена и платформа вызовет исключение «В данной транзакции происходила ошибка»НачатьТранзакцию();
Попытка
БлокировкаДанных = Новый БлокировкаДанных;
ЭлементБлокировкиДанных = БлокировкаДанных.Добавить("Документ.ПриходнаяНакладная");
ЭлементБлокировкиДанных.УстановитьЗначение("Ссылка", СсылкаДляОбработки);
ЭлементБлокировкиДанных.Режим = РежимБлокировкиДанных.Исключительный;
БлокировкаДанных.Заблокировать();
. // чтение или запись данных
ЗаписьЖурналаРегистрации(НСтр("ru = 'Выполнение операции'"),
УровеньЖурналаРегистрации.Ошибка,
,
,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
ВызватьИсключение; // есть внешняя транзакция
1.4. Использование вложенных транзакций приводит к усложнению кода. Принимая решение об использовании этой возможности, нужно очень взвешенно оценить решаемую задачу: возможно, это усложнение просто не оправдано.
1.4.1. Не стоит усложнять код, явно используя метод НачатьТранзакцию , когда кроме записи объекта другие действия c базой данных не делаются – платформа при записи сама откроет транзакцию.
Не нужно явно открывать транзакцию тогда, когда не требуется выполнять ответственное чтение данных. Например, обычно ответственное чтение не требуется при записи нового объекта (нового набора записей регистра).
При использовании методов ПолучитьОбъект (или Прочитать для наборов записей) необходимо анализировать должно ли чтение быть отвественным и в зависимости от этого принимать решение о явном использовании метода НачатьТранзакцию .
Попытка
ДокументОбъект = Документы.ПриходнаяНакладная.СоздатьДокумент();
. // действия по заполнению объекта
ДокументОбъект.Записать();
Исключение
. // действия по обработке исключения
КонецПопытки;
НачатьТранзакцию();
Попытка
ДокументОбъект = Документы.ПриходнаяНакладная.СоздатьДокумент();
. // действия по заполнению объекта
ДокументОбъект.Записать();
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
КонецПопытки;
1.4.2. Если метод рассчитан на вызов только в рамках уже открытой транзакции (например, метод предназначен для вызова только из событий ПередЗаписью , ОбработкаПроведения и т.п.) в общем случае явным образом открывать в нем транзакцию не имеет никакого практического смысла.
1.4.4. При обработке исключения, если транзакция все еще активна, например, исключение возникло во вложенной транзакции, нельзя обращаться к базе данных, так как это приведет к исключению «В этой транзакции уже происходили ошибки». При этом нужно учитывать, что обращение к базе данных может быть неявным, например, для получения представления ссылки.
2. Ограничение на длину транзакции.
2.1. В общем случае в рамках одной транзакции нужно выполнять только те действия, которые неделимы, исходя из бизнес-логики.
При проведении документа записывается документ и его движения в регистрах. Если не прошла запись хотя бы в один регистр вся операция проведения должна быть отменена.
2.1.1. Если с точки зрения бизнес-логики действия могут быть выполнены по отдельности, то их в общем случае не следует объединять в одну транзакцию.
2.1.2. Исключением из п.2.1.1 могут быть случаи, когда с целью оптимизации несколько несвязанных объектов обрабатываются в рамках одной транзакции. В этом случае необходимо взвешенно подходить к выбору порции обработки данных: нужно стремиться к достижению золотой середины между длительностью одной транзакции и объемом фиксируемых данных с одной стороны и количеством транзакций с другой.
2.2. Следует избегать транзакций, которые выполняются длительное время.
Для загрузки адресного классификатора ФИАС записывать все данные, относящиеся к одной версии классификатора в одной транзакции, для того, чтобы в случае ошибки откатить целиком загружаемую версию классификатора.
Т.к. данных по одной версии классификатора много (объем около 1 Гб), то для выполнения такой транзакции, во-первых, может не хватить оперативной памяти (особенно при использовании файловой информационной базы на 32-разрядной ОС), а, во-вторых, такая операция будет выполняться достаточно долго и ее нельзя будет оптимизировать за счет выполнения в несколько потоков.
Разбить загрузку новой версии классификатора ФИАС на небольшие транзакции и реализовать функциональность по откату к предыдущей версии в случае ошибки.
2.2.1 Чем дольше выполняется транзакция, тем большее время будут заняты ресурсы сервера 1С:Предприятия и СУБД. Как правило длинные транзакции занимают следующие ресурсы:
- в ходе выполнения транзакции все изменения в базе данных записываются в журнал транзакций, что необходимо для возможности откатить транзакцию;
- блокировки, установленные в транзакции, остаются до конца транзакции;
- на сервере 1С:Предприятия блокировки занимают оперативную память;
- другие ресурсы, необходимые самой бизнес-логике, которая выполняется в транзакции.
Все это в целом может снижать эффективность использования ресурсов.
2.2.2. Если две транзакции пересекаются по блокируемым ресурсам, то транзакция, которая начала выполняться позже, будет ожидать возможность установления блокировки ограниченное время (по умолчанию – 20 секунд), после чего будет завершена с исключением «Превышено время ожидания установки блокировки». Поэтому длинные транзакции могут сильно снижать удобство параллельной работы пользователей.
Возникновение таких исключений – это повод провести анализ действий, которые выполняются в конфликтующих транзакциях
возможно, какие-то действия можно вынести за транзакцию (см. п. 2.4); если действие вынести нельзя, то нужно постараться оптимизировать алгоритм его выполнения; так же нужно проанализировать оптимальность устанавливаемых блокировок (см. группу стандартов Избыточные блокировки и методы оптимизации )2.3. В рамках транзакции нужно стремиться выполнять минимум действий – только те, которые нельзя в соответствии с бизнес-логикой выполнять вне транзакции. В частности:
Кэш объектов в 1С состоит из двух частей - "Обычный кэш" и "Транзакционный кэш" .
Обычный кэш .
Уникальным идентификатором для кэша является ссылка на объект базы данных. Поэтому в кэше хранится или объект целиком со всеми своими данными, или представление объекта.
Если запросить у кэша представление объекта и там оно есть, то это представление будет взято из кэша . Если в кэше не представление объекта, а весь объект, то представление будет сформировано на основе данных объекта, хранящегося в кэше . Если же ни того, ни другого в кэше нет, то в кэш из базы данных будут считаны только поля, необходимые для запроса.
Если запросить у кэша реквизит объекта, и в кэше есть этот объект, то без проблем - кэш сразу вернёт этот реквизит. Если в кэше только представление объекта, то кэш не будет и пытаться искать в нём нужный реквизит, а просто удалит его, скачает из базы данных весь объет и будет выковыривать реквизит из него.
Обычный кэш удаляет у себя данные ещё в следующих случаях:
1. Поступают новые данные, а их негде хранить - закончилось свободное место. Тогда самые старые данные удаляются.
2. Если при повторном обращении к данным, уже находящимся в кэше прошло более 20 секунд, кэш сверяет эти данные с базой данных, и если в базе данных они изменились, то удаляет их у себя и скачивает взамен из базы данных их новую версию.
3. Прошло более 20 минут после того, как данные были помещены в кэш .
Транзакционный кэш .
Транзакция - это неделимая последовательность операций с данными, переводящая базу данных из одного целостного состояния в другое. То есть, если какая-либо операция не просто обращается к базе данных, а производит в ней изменения, то она упаковывается вместе со всеми сопутствующими операциями в транзакцию . И если хоть одну операцию из транзакции нельзя выполнить, то все операции из этой транзакции отменяются и база данных возвращается в состояние, в котором она была до начала транзакции (это называется откат транзакции - Rollback ).
В отличие от обычного кэша , транзакционный кэш не проверят данные на валидность, если прошло более 20 секунд от последнего обращения, а просто блокирует изменение в базе тех данных, которыые он взял из базы данных, пока транзакция не завершится.
Транзакционный кэш удаляет у себя данные в следующих случаях:
1. Поступают новые данные, а их негде хранить - закончилось свободное место. Тогда самые старые данные удаляются.
2. Транзакция завершилась неуспешно.
3. Транзакция завершилась успешно. Тогда данные переносятся в обычный кэш .
Читайте также: