Возможно проблема кэширования 1с

Форум 1С: Одинэс.Ру

Найти!

Возможно проблема кэширования 1с

parcan
28.04.2009 - 13:45
Поднимал уже такую тему на infostart.ru попробую и тут.
.
С ЧЕГО НАЧАЛАСЬ ТЕМА
.
Попытаюсь понятно сформулировать свою ситуацию:
Общее:
На точках стоит программа написанная на 1с (написана мною, код знаю как свои 5 пальцев). Продавец запускает программу (это один процесс) в которой осуществляет продажи. Первый процесс при старте запускает второй (фоновый) процесс 1с, который периодически отправляет данные с точки в офис и подгружает данные из офиса. Используется файловый вариант работы 1с. На точках используются 2 релиза платформы 8.1.12.98 и 8.1.13.37. Все действия производимые обоими процессами программы подробно пишутся в лог-файлы и логи соответственно присылаются ко мне.
Существует документ смена, который создается пустой (заполнены только номер и дата) при открытии смены в магазине. Вечером продавец делает закрытие смены и этот документ перезаписывается с заполненными данными. Далее фоновый процесс отправляет данные этого документа в офис. Каждый объект имеет реквизит статус типа перечисления в котором хранится текущий статус объекта (не выгружен, выгружен в офис, загружен в офисе, отклонен в офисе) фоновый процесс ориентируется по этим статусам что ему делать.
Проблема:
Периодически на различных точках фоновый процесс при выгрузке документа как будто получает старую версию документа в которой еще не заполнены данные.
Попытаюсь провести объяснение последовательности происходящих событий по своему логу с пояснениями:
.
Утром продавец открывает смену, записан документ смена с заполненными датой и номером, все остальные реквизиты пустые.
22.04.2009 8:37:51 kassir Открыта смена : Смена 16 от 22.04.2009 8:37:51
.
Вечером продавец закрывает смену, перезаписан документ с заполненными параметрами, тут привожу только ДатаЗакрытия.
22.04.2009 22:33:47 kassir (до записи объекта) Документ объект: Смена Номер: 16 Дата: 22.04.2009 8:37:51 ДатаЗакрытия: 22.04.2009 22:33:47
22.04.2009 22:33:47 kassir Закрыта смена : Смена 16 от 22.04.2009 8:37:51
22.04.2009 22:33:47 kassir (после записи объекта) Документ объект: Смена Номер: 16 Дата: 22.04.2009 8:37:51 ДатаЗакрытия: 22.04.2009 22:33:47
.
Далее робот (фоновый процесс) выполняет запрос документов смена в которых реквизит ДатаЗакрытия <> Дата(1,1,1) и по полученным ссылкам выгружает данные.
22.04.2009 22:33:49 robot (при выгрузке) Документ ссылка: Смена Номер: 16 Дата: 22.04.2009 8:37:51 ДатаЗакрытия: 01.01.0001 0:00:00
Получается, что при выполнении запроса у документа смена реквизит ДатаЗакрытия заполнен, а вот в полученной ссылке из запроса этот реквизит уже не заполнен (как впрочем и все остальные).
При выгрузке документа фоновый процесс robot вновь перезаписывает документ меняя ему статус на выгружен. В итоге оказывается записан документ со статусом выгружен, но с пустыми реквизитами.
.
Далее может оказаться еще интереснее. Продавец печатает отчет за последнюю смену. Через МенеджерДокументов получаем ссылку на последний документ и выводим его данные
22.04.2009 22:34:00 kassir Напечатана строка: ДАТА ОТКР.: 22.04.2009 08:37:51
22.04.2009 22:34:00 kassir Напечатана строка: ДАТА ЗАКР.: 22.04.2009 22:33:47
Получается, что у продавца в документе данные все еще заполнены, но так бывает редко, обычно после робота и у продавца документ уже тоже имеет пустые данные.
.
В результате после всего этого в базе остался документ с незаполненными реквизитами.
Закономерности этой проблемы выявить не смог, может несколько дней на всех точках работать все нормально, а потом на некоторых происходить такой косяк.
При перезаписи объекта стал использовать Получить() ничего не изменилось.
Код промониторил вдоль и поперек все выполняется четко.
Операции выводимые в лог длятся меньше секунды, т.е. их последовательность точно не нарушена.
.
Единственное оставшееся у меня предположение, что это как то связано с кэшированием данных либо самой 1с либо системы в целом.
.
ЧЕМ ЗАКОНЧИЛАСЬ ТЕМА
.
После обсуждения был еще более детализирован лог и добавлена подписка на событие ПриЗаписи() для документа Смена.
.
В итоге событие ПриЗаписи() никогда не отрабатывает лишний раз и нет никакого обнуления документа Смена.
.
Но интересен лог для следующего кода в фоновом процессе робота
 
//*********************************************
Процедура ОбработатьПродажи(ТолькоНовые=Истина)
  
   МассивСтатусов = Новый Массив;
   МассивСтатусов.Добавить(Перечисления.СтатусыФайловогоОбмена.ПустаяСсылка());
   МассивСтатусов.Добавить(Перечисления.СтатусыФайловогоОбмена.Создан);
   Если Не ТолькоНовые Тогда   //выгруженные
       МассивСтатусов.Добавить(Перечисления.СтатусыФайловогоОбмена.Выгружен);
   КонецЕсли;
  
   Запрос = Новый Запрос("ВЫБРАТЬ
                         |   Смена.Ссылка КАК Ссылка
                         |ИЗ
                         |   Документ.Смена КАК Смена
                         |ГДЕ
                         |   Смена.ДатаЗакрытия <> &ПустаяДата
                         |   И Смена.Статус В(&СтатусыФайловогоОбмена)
                         |УПОРЯДОЧИТЬ ПО
                         |   Смена.Дата"
                         |;
                         |
                         |//////////////////////////////////////////////////­//////////////////////////////
 
                         |ВЫБРАТЬ
                         |   Чек.Ссылка КАК Ссылка
                         |ИЗ
                         |   Документ.Чек КАК Чек
                         |ГДЕ
                         |   Чек.Статус В(&СтатусыФайловогоОбмена)
                         |
                         |УПОРЯДОЧИТЬ ПО
                         |   Чек.Дата
                         |;
                         |
                         |//////////////////////////////////////////////////­//////////////////////////////
 
                         |ВЫБРАТЬ
                         |   ВнесениеИзъятие.Ссылка КАК Ссылка
                         |ИЗ
                         |   Документ.ВнесениеИзъятие КАК ВнесениеИзъятие
                         |ГДЕ
                         |   ВнесениеИзъятие.Статус В(&СтатусыФайловогоОбмена)
                         |
                         |УПОРЯДОЧИТЬ ПО
                         |   ВнесениеИзъятие.Дата");
   Запрос.УстановитьПараметр("ПустаяДата", Дата(1,1,1));
   Запрос.УстановитьПараметр("СтатусыФайловогоОбмена", МассивСтатусов);
  
   МассивРезультатов = Запрос.ВыполнитьПакет();
   МассивСмен = МассивРезультатов[0].Выгрузить().ВыгрузитьКолонку("Ссылка");
   МассивЧеков = МассивРезультатов[1].Выгрузить().ВыгрузитьКолонку("Ссылка");
   МассивВнесенийИзъятий = МассивРезультатов[2].Выгрузить().ВыгрузитьКолонку("Ссылка");
  
   Для Каждого Смена Из МассивСмен Цикл
      _Временный._ВывестиВЛогДанныеСмены(Смена, "(результат запроса робота)");
   КонецЦикла;
  
   СформироватьПродажи(МассивСмен, МассивЧеков, МассивВнесенийИзъятий);
  
КонецПроцедуры // ОбработатьПродажи()
//*********************************************
.
В _Временный._ВывестиВЛогДанныеСмены(ОбъектИлиСсылка, Описание) происходит только запись в лог-файл и ничего более.
.
Данные из лог-файла:
27.04.2009 22:31:02 robot (результат запроса робота) Документ ссылка: Смена Номер: 2 Дата: 27.04.2009 7:59:56 ДатаЗакрытия: 01.01.0001 0:00:00
.
При выполнении запроса ДатаЗакрытия заполнена сразу после выполнения запроса ДатаЗакрытия пустая. Никаких изменений объекта Смена в это время не происходит, т.е. подписка на событие ПриЗаписи() не отрабатывает (в подписке на событие для логирования тоже вызываеться _Временный._ВывестиВЛогДанныеСмены(Источник, "(подписка на событие)"))
.
По всему набору имеющихся лог-файлов с проблемами выяснил что от времени выполнения запроса в процессе робота и сохранения смены в процессе продавца это не зависит, т.е. разница во времени составляла от 0 секунд до почти 4х минут во всем промежутке этого времени косяк может произойти, а может не произойти.
На данный момент вероятность появления косяка варьируется в пределах 0-20%.
.
в общем волшебство :)
К списку тем 1 > К списку форумов

Интересные темы

odines.ru
03.05.2024 - 18:58
Смотри также:
Ошибка работы с временными таблицами в построителе
Как сделать зачет с договора в ЕВРО на договор в рублях по одному контрагенту
v8: Несколько Розниц и одна Управление торговлей, как настроить...

Re: Возможно проблема кэширования 1с

dot
14 - 29.04.2009 - 09:23
про кэш есть инфа в книге Радченко Практическое пособие разработчика.
объект в обычном кэше хранится 20 минут, а также в пределах 20 секунд данные объекта считаются валидными. кэш делится на обычный и транзакционный. я думаю нужно роботу получать ссылку в транзакции. может в этом все дело?

Re: Возможно проблема кэширования 1с

parcan
15 - 29.04.2009 - 10:10
(14) почитаю книжку. Можно насчет транзакции поподробней мысль, я всегда считал что транзакция имеет смысл только в случае многочисленной записи для ускорения или для объединения нескольких действий в одно целое но опять же при записи.

Re: Возможно проблема кэширования 1с

dot
16 - 29.04.2009 - 14:02
Радченко пишет, что в транзакционном кэше все данные считаются валидными, и после фиксации транзакции транзакционный кэш очищается. еще можно попробовать при получении ссылки на док блокировать эти данные, тогда скорее всего произойдет проверка валидности данных в обычном кэше. 1с размещает кэш в оперативной памяти.

Re: Возможно проблема кэширования 1с

parcan
17 - 29.04.2009 - 14:16
С партнерской конференции
 
Адининский Александр (Хьюмен Систем, Минск)
Есть 2 компоненты одного программного решения - серверная и клиентская части. При их работе выявилась такая проблема (по этапам):
 
1) Клиентская часть выполняет соединение с базой через COMConnector.
(VB)
Set COMConnector = CreateObject("V8.COMConnector")
Set COMConnect = COMConnector.Connect(ConString)
 
2) Клиентская часть получает представление элемента справочника
ExtRefPresentation = COMConnect.String(ExtRef)
 
3) Серверная часть через COM-соединение выполняет изменение элемента справочника (изменяет наименование).
 
4) Клиентская часть пытается получить представление и получает СТАРОЕ значение. Новое представление удается получить, только выполнив подключение через COM еще раз.
 
Это ошибка платформы? Если нет, то почему так может происходить, если да - как обойти эту проблему?
 
Виктор Сосновский (1С, Москва)
Если клиентская часть удерживает объект "СправочникОбъект" на переменной ExtRef, то обновление элемента справочника серверной частью вносит изменение в запись базы данных, но не может внести изменение в объект "СправочникОбъект", который удерживается на переменной ExtRef клиентской частью. Чтобы изменения в базе данных отразились в объекте необходимо выполнить метод "Прочитать" этого объекта или получить новый объект "СправочникОбъект".
 
Адининский Александр (Хьюмен Систем, Минск)
Во избежание описанных проблем и клиентская и серверная части используют ссылки на объекты 1С. Захват самого объекта происходит _только_ при изменении данных.
Для получения представления захват объекта, естественно, не нужен, соответственно ExtRef - ссылка.
 
Виктор Сосновский (1С, Москва)
Если ExtRef - ссылка, то получение ее представления выполняется через кеш представлений, который в описанной ситуации может содержать устаревшие данные. При необходимости получения гарантированно актуальных данных необходимо получение данных выполнять в транзакции.
 
Адининский Александр (Хьюмен Систем, Минск)
При каких условиях или через какой интервал времени кэш представлений обновляется? И касается ли эта ситуация ТОЛЬКО представления объекта, или любых его данных (если я вдруг захочу получить не представление, а наименование например).

Re: Возможно проблема кэширования 1с

parcan
18 - 29.04.2009 - 14:18
(16) Попробовать в запросе использовать конструкцию "ДЛЯ ИЗМЕНЕНИЯ" Блокировать получаемые данные для последующего изменения?

Интересные темы

odines.ru
03.05.2024 - 18:58
Смотри также:
Доступ и т.д. Не могу понять почему неактивные окошки
Кто работал с компоненнтой optikom_v.dll
Расчет пени

Re: Возможно проблема кэширования 1с

dot
19 - 29.04.2009 - 15:03
да, я думаю поможет, ну или в транзакцию все оформить.

Re: Возможно проблема кэширования 1с

dot
20 - 29.04.2009 - 15:08
если в запросе использовать данную конструкцию, то данные из кэша будут проверены на валидность перед блокировкой. по сути таже транзакция.

Re: Возможно проблема кэширования 1с

dot
21 - 29.04.2009 - 15:19
но я не специалист в механике 1с, просто догадки и мельком прочитаный радченко, поэтому надо проверять все на практике :)

Re: Возможно проблема кэширования 1с

parcan
22 - 29.04.2009 - 16:01
(21) если это поможет с меня пиво, ты где проживаешь?

Re: Возможно проблема кэширования 1с

parcan
23 - 30.04.2009 - 10:17
Использование предложения «ДЛЯ ИЗМЕНЕНИЯ» в языке запросов
Предложение ДЛЯ ИЗМЕНЕНИЯ позволяет заблаговременно заблокировать некоторые данные (которые могут читаться транзакцией другого соединения) уже при считывании, чтобы исключить взаимные блокировки при записи. ДЛЯ ИЗМЕНЕНИЯ дает возможность указать в запросе таблицы, считываемые данные которых предполагается изменять. В этом случае другое соединение будет ожидать освобождения этих данных уже в момент считывания внутри транзакции, т.е. не сможет прочесть заблокированные данные до тех пор, пока не будет завершена транзакция, наложившая блокировку. Блокировка от изменения данных считываемых в транзакции выполняется независимо от предложения ДЛЯ ИЗМЕНЕНИЯ. Это значит, что если внутри какой-либо транзакции считаны некоторые данные, то из другого соединения эти данные не могут быть изменены до тех пор, пока блокировка не будет снята. Если запрос выполняется вне транзакции, то в нем могут быть считаны и заблокированные данные.
Блокировки устанавливаются в момент выполнения запроса, сбрасываются же при окончании транзакции. В случае если запрос выполняется вне транзакции предложение ДЛЯ ИЗМЕНЕНИЯ игнорируется.
 
похоже конструкция «ДЛЯ ИЗМЕНЕНИЯ» смысла тут не имеет, а вот транзакция имеет.
К списку тем 1 > К списку форумов

Добавить новое сообщение

Ваше имя:
Тема сообщения:
Сообщение:
« База запаролена, как войти? Проблема с формированием баланса в БП релиз 1.6.13.3 »
© 2009 Форум 1С: Одинэс.Ру