Работа в распределенных информационных базах (РИБ) на платформе 1С — это всегда баланс между стабильностью каналов связи, производительностью СУБД и корректностью программного кода. Иногда администраторы и разработчики сталкиваются с аномальным поведением системы: обмен данными работает исправно месяцами, но в какой-то момент регистрация изменений по определенным объектам полностью прекращается. При этом в Журнале регистрации нет абсолютно никаких ошибок, а сама проблема через несколько дней может «самопроизвольно» исчезнуть.
Давайте подробно разберем эту ситуацию на примере конфигурации УПП (Управление производственным предприятием) и выясним, какие скрытые механизмы платформы и особенности СУБД могут приводить к избирательному отказу регистрации изменений.
ОбменДанными.ЗагрузкаПервое, на что стоит обратить внимание при анализе механизмов обмена — это использование свойства ОбменДанными.Загрузка при записи объектов. В стандартных конфигурациях 1С (особенно построенных на базе Библиотеки стандартных подсистем или классических решений вроде УПП) это свойство регулирует поведение подписок на события и встроенных обработчиков конфигурации.
Когда данные записываются программно (например, при загрузке из внешних систем, работе обработок группового изменения или интеграциях), разработчики часто устанавливают признак загрузки в значение Истина:
Объект.ОбменДанными.Загрузка = Истина;
Объект.Записать();
Рассмотрим, к чему это приводит. В платформе 1С при установке этого свойства отключается большинство стандартных проверок в модулях объектов, а также блокируется выполнение подписок на события, которые отвечают за авторегистрацию изменений. Если в вашей базе регистрация реализована через подписки на события перед записью или при записи (что является стандартом для многих конфигураций), то использование ОбменДанными.Загрузка = Истина полностью заблокирует попадание объекта в план обмена.
Для решения этой проблемы необходимо проанализировать код кастомных обработок, регламентных заданий и внешних интеграций, работавших в период сбоя. Если запись объектов выполнялась с этим флагом, следует пересмотреть логику: либо регистрировать изменения принудительно, либо отказаться от флага в пользу стандартной записи. Для быстрой отправки пропущенных данных подойдёт обработка для массовой регистрации объектов к обмену.
Еще один частый сценарий программного обхода регистрации изменений — это манипуляция коллекцией получателей конкретного объекта. У каждого объектного типа данных в 1С есть свойство ОбменДанными.Получатели, которое управляет тем, для каких именно узлов планов обмена будет зарегистрировано изменение при записи.
Разберем пример кода, который разработчики используют для «тихой» записи объекта без его миграции по сети распределенной базы:
Объект.ОбменДанными.Получатели.АвтоЗаполнение = Ложь;
Объект.ОбменДанными.Получатели.Oчистить();
Объект.Записать();
Если этот код выполняется в контексте работы обычного пользователя (например, при проведении документа через кастомную кнопку, регламентную процедуру или при проведении зависимых документов), объект запишется в базу успешно, но в таблицу регистрации изменений не попадет. При этом никаких записей об ошибках в Журнале регистрации не появится, так как с точки зрения платформы это штатное, задокументированное поведение.
Рекомендуется выполнить глобальный поиск по конфигурации и внешним обработкам по ключевому слову АвтоЗаполнение = Ложь, чтобы локализовать места, где разработчики могли намеренно или случайно отключить авторегистрацию.
Если сбой в регистрации носил временный характер (продолжался ровно два дня и затрагивал разных пользователей и разные объекты), одной из наиболее вероятных причин является проведение динамического обновления конфигурации базы данных.
Динамическое обновление (когда изменения вносятся в базу без монопольного выгона пользователей) — известная зона риска для платформы 1С. При этом процессе на сервере приложений или на рабочих станциях пользователей кэш метаданных может обновиться некорректно. Рассмотрим последствия этого сбоя:
Выясним, как с этим бороться. Единственный надежный способ устранить последствия такого сбоя — это полная очистка кэша на сервере 1С:Предприятие (перезапуск службы сервера с предварительным удалением папки сомнительных кэшей) и очистка локального кэша у пользователей. Это полностью объясняет, почему через 2 дня (например, после планового перезапуска сервера в выходные) проблема исчезла сама собой.
Попытка — ИсключениеПроанализируем ситуацию, когда регистрация изменений прописана программно в модулях конфигурации. Очень часто разработчики, пытаясь обезопасить транзакцию записи основного документа от падения из-за ошибок обмена, оборачивают вызов регистрации в блок обработки исключений.
Посмотрим на классический пример опасного кода:
Попытка
ПланыОбмена.ЗарегистрироватьИзменения(УзелОбмена, ОбъектСсылка);
Исключение
// Ошибка перехвачена, но никак не обработана и не записана в журнал
КонецПопытки;
В случае возникновения любой нештатной ситуации (например, кратковременная блокировка таблицы регистрации на уровне СУБД, нехватка прав доступа у конкретного пользователя на чтение узла плана обмена, повреждение структуры базы данных), платформа перейдет в ветку Исключение. Объект будет успешно записан в базу данных, транзакция зафиксируется, но регистрация изменений «молча» сорвется.
Давайте перепишем этот блок кода правильно, с обязательной фиксацией проблемы в Журнале регистрации:
Попытка
ПланыОбмена.ЗарегистрироватьИзменения(УзелОбмена, ОбъектСсылка);
Исключение
ЗаписатьВЖурналРегистрации(
"ОбменДанными.ОшибкаРегистрации",
УровеньЖурналаРегистрации.Ошибка,
ОбъектСсылка.Метаданные(),
ОбъектСсылка,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())
);
КонецПопытки;
Используя правильную обработку исключений, вы всегда будете видеть реальную картину происходящего в Журнале регистрации.
На высоконагруженных базах данных, таких как УПП, критически важным фактором является производительность СУБД (MS SQL Server, PostgreSQL). Для каждого плана обмена в базе данных создаются служебные таблицы регистрации изменений. На уровне СУБД они имеют постфикс _ChngR.
При интенсивной работе пользователей (например, массовое проведение документов, проведение тяжелых цепочек документов, групповое перепроведение за прошлые периоды) таблицы регистрации подвергаются частым операциям записи и удаления. Рассмотрим механизм возникновения проблемы:
_ChngR.Если в вашем плане обмена используются сложные правила регистрации объектов (настроенные, например, через «Конвертацию данных» или встроенные механизмы БСП), логика регистрации перестает быть линейной.
Рассмотрим две важные настройки, которые могут сымитировать сбой регистрации:
Если вы снова столкнулись с тем, что объекты перестали регистрироваться в плане обмена, рекомендуем действовать по следующему алгоритму:
ОбменДанными.Загрузка = Истина или очищать коллекцию получателей.