Почему добавление регистров в движения документа не всегда позволяет выполнить динамическое обновление?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

В процессе сопровождения крупных и «поживших» конфигураций 1С программисты часто сталкиваются с необходимостью расширения функционала существующих документов. Одной из таких задач является добавление новых регистров в список движений документа. Казалось бы, это простое изменение метаданных, но на практике система ведет себя по-разному: в одних случаях обновление проходит мгновенно (динамически), а в других — платформа требует выгнать всех пользователей для проведения реструктуризации. Разберем подробно, почему так происходит и какая техническая логика стоит за этими процессами.

Взаимосвязь состава регистраторов и структуры таблиц СУБД

Проанализируем ситуацию с точки зрения того, как платформа 1С хранит данные на уровне SQL-сервера. Ключевым моментом здесь является поле Регистратор, которое присутствует в каждой таблице движений регистров накопления, сведений или бухгалтерии. Рассмотрим два сценария состояния регистра в конфигурации:

  1. У регистра только один регистратор: В этом случае на уровне СУБД поле _RecorderRRef (или аналогичное) имеет фиксированный тип данных (обычно binary(16)). Платформа «знает», что в этом регистре могут быть записи только одного типа документа, поэтому ей не нужно хранить идентификатор типа документа в каждой строке таблицы.
  2. У регистра два и более регистраторов: Как только в списке регистраторов появляется второй документ, тип поля становится составным. Для поддержки составного типа платформа добавляет в таблицу СУБД еще одно поле — _RecorderTRef. Это поле хранит идентификатор типа метаданных, чтобы система понимала, к какому именно виду документа относится ссылка _RecorderRRef.

Выясним причину блокировки динамического обновления: Если вы добавляете второй регистратор к регистру, который до этого имел только один, платформа вынуждена выполнить команду ALTER TABLE для добавления новой колонки _RecorderTRef. Любое изменение физической структуры таблицы (добавление колонок, изменение типов существующих колонок) — это и есть реструктуризация. Именно поэтому в такой ситуации динамическое обновление («демоническое», как его называют в шутку) невозможно.

Если же у регистра уже было два или более регистратора, добавление третьего, четвертого и последующих не меняет физическую структуру таблицы в SQL. Поле _RecorderTRef уже существует, оно уже настроено на хранение составного типа. Платформа просто обновляет свои внутренние таблицы описания метаданных, что позволяет выполнить обновление без монопольного захвата базы.

Влияние последовательностей и планов обмена

Рассмотрим другие механизмы, которые могут накладывать вето на динамическое обновление при изменении движений документа. Даже если вопрос с составным типом поля решен, существуют связанные объекты метаданных.

Последовательности документов: Если регистр накопления входит в какую-либо последовательность, то при добавлении нового регистратора платформа обязана внести изменения в служебные таблицы этой последовательности. Это необходимо для корректного контроля границ последовательности при проведении нового типа документа. Такие изменения часто требуют реструктуризации служебных таблиц последовательностей.

Планы обмена (РИБ): Проанализируем ситуацию с распределенными информационными базами. Если регистр или документ участвуют в обмене с авторегистрацией, добавление связи между ними меняет логику работы таблиц регистрации изменений (таблицы с префиксом _Chng). Платформа должна гарантировать, что структура данных для миграции идентична на всех узлах. Чтобы избежать коллизий при выгрузке данных, система блокирует динамическое изменение состава движений в таких объектах.

Оптимизация реструктуризации в новых версиях платформы

Начиная с версии платформы 8.3.11, механизмы реструктуризации были существенно оптимизированы. Рассмотрим, что изменилось. Раньше любая реструктуризация подразумевала создание временной таблицы, копирование туда всех данных, удаление старой таблицы и переименование новой. Это был крайне долгий процесс.

Современные версии платформы стараются выполнять «минимальную» реструктуризацию. Например, если в базе включена возможность фоновой реструктуризации (доступно в версии CORP), некоторые операции могут выполняться почти незаметно для пользователей. Однако для обычных лицензий требование монопольного режима остается в силе, если затрагиваются критические поля СУБД.

Риски динамического обновления («демонического» режима)

Несмотря на то, что платформа иногда позволяет «пробросить» изменения в движениях динамически, проанализируем, почему этого стоит избегать в продуктивных базах. Проблема заключается в кэшировании метаданных на стороне сервера приложений и клиентских сеансов.

Когда вы добавляете регистр в движения документа, объект Metadata изменяется. После динамического обновления может возникнуть ситуация «рассинхрона»:

Посмотрим на пример того, как это может выглядеть в коде при попытке программного обращения к новым движениям сразу после «удачного» динамического обновления:


// Этот код может упасть с ошибкой в сеансе, который не был обновлен
Попытка
    НаборДвижений = Движения.НовыйДобавленныйРегистр;
    НаборДвижений.Записать();
Исключение
    Сообщить("Ошибка обращения к метаданным: " + ОписаниеОшибки());
КонецПопытки;

Рекомендации по выполнению обновлений

Подводя итог, разберем алгоритм действий для безопасного добавления регистров в движения, включая запуск процедур обработчиков обновления при необходимости:

  1. Проверьте текущее количество регистраторов у регистра. Если он один — готовьтесь к полноценной реструктуризации с выгоном пользователей.
  2. Проверьте, не входит ли регистр в последовательности или планы обмена. Если входит — динамическое обновление крайне нежелательно, даже если применяются помощники обновления на базе ИИ для автоматизации.
  3. Если база работает в режиме 24/7 и реструктуризация неизбежна, рассмотрите возможность использования механизма фоновой реструктуризации (если позволяет лицензия).
  4. Всегда выполняйте обновление конфигурации базы данных через «Обновить конфигурацию базы данных» (F7), а не через «Динамическое обновление», если затрагиваются метаданные регистров.
  5. После любого обновления, даже если платформа позволила сделать его динамически, настоятельно рекомендуется перезапустить все рабочие процессы сервера (или попросить пользователей перезайти в систему), чтобы гарантированно очистить кэш метаданных.

Важный момент: если вы случайно обнаружили, что обновление «проскочило» динамически, обязательно проверьте работоспособность механизма корректировки движений (или того функционала, ради которого вносились правки). Ошибки кэша могут проявиться не сразу, а только при определенных действиях пользователей, что усложнит диагностику проблемы в будущем.

← На главную