Почему пропадают изменения при помещении в хранилище после динамического обновления в 1С 8.3?

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

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

В этой статье мы подробно разберем, почему возникает этот критический баг, какую роль в этом процессе играет СУБД (PostgreSQL или MS SQL Server), и как полностью обезопасить свою конфигурацию от потери программного кода.

Выясняем причину: механизм работы бага кэширования

Описанное поведение системы не связано со сбоями в СУБД, хотя на первый взгляд может показаться именно так. Это классический зарегистрированный баг самой платформы «1С:Предприятие 8.3» (в частности, зарегистрированный в базе ошибок под кодом 000035297). Наиболее массово эта проблема проявлялась на релизах ветки 8.3.10 (например, 8.3.10.2639, 8.3.10.2580), но схожие проявления рассинхронизации метаданных периодически встречаются и в более поздних версиях платформы.

Проанализируем ситуацию по шагам, чтобы понять, как именно «ломается» кэш Конфигуратора:

  1. В Базе №1 (подключенной к хранилищу) разработчик захватывает объект, меняет его структуру или модуль, выполняет динамическое обновление конфигурации базы данных и успешно помещает изменения в хранилище.
  2. В это время в Базе №2 открыт Конфигуратор. Из-за того, что в первой базе было выполнено динамическое обновление, локальный кэш конфигурации во второй базе «залипает». Он перестает корректно отслеживать актуальные версии метаданных, хранящиеся в СУБД и в хранилище.
  3. Когда разработчик в Базе №2 нажимает кнопку «Получить из хранилища», Конфигуратор сравнивает версии объектов. Из-за сбойного кэша система ошибочно считает, что локальная версия объекта во второй базе полностью идентична новой версии из хранилища. Обновления кода физически не происходит.
  4. Если второй разработчик выполняет захват этого объекта, Конфигуратор осуществляет «тихий» захват устаревшей локальной версии. При её последующем изменении и помещении обратно в хранилище новые доработки первого разработчика бесследно затираются старым кодом.

Миф о PostgreSQL: влияет ли СУБД на потерю данных?

Очень часто разработчики начинают грешить на PostgreSQL, замечая проблему сразу после миграции с MS SQL Server (особенно при переходе с бесплатной версии MS SQL Express из-за превышения лимита на размер базы данных). Однако тип используемой СУБД не влияет на появление этого бага. Ошибка одинаково воспроизводится как на файловых базах, так и на клиент-серверных вариантах под управлением MS SQL Server, PostgreSQL, IBM DB2 или Oracle.

Ложное подозрение на PostgreSQL возникает по двум причинам:

Как решить проблему: пошаговое руководство

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

Способ 1. Полная очистка локального кэша 1С

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

Разберем, как сделать это вручную:

  1. Закройте все запущенные сеансы «1С:Предприятие» и Конфигураторы на компьютере разработчика.
  2. Перейдите в директорию временных файлов вашего профиля Windows. Обычно они располагаются по пути:
    %localappdata%\1C\1Cv8 (например, C:\Users\ИмяПользователя\AppData\Local\1C\1Cv8)
    и %appdata%\1C\1Cv8 (например, C:\Users\ИмяПользователя\AppData\Roaming\1C\1Cv8).
  3. Удалите все папки с длинными шестнадцатеричными именами (состоящими из букв и цифр, например, 1eb89f56-626a-493e-bc5d-df10a5198e3b). Именно в этих каталогах хранятся служебные кэши конфигурации, включая Config, ConfigSave, DBNameCache и SICache.
  4. Запустите Конфигуратор заново и выполните полное получение конфигурации из хранилища.

Способ 2. Очистка кэша на уровне СУБД (при критических падениях)

В некоторых случаях динамическое обновление в связке с хранилищем приводит к повреждению структуры базы данных на уровне таблиц SQL. При попытке запустить базу пользователи видят сообщение «Ошибка формата потока». В этом случае требуется реанимация базы данных на уровне СУБД.

Рассмотрим пример SQL-скрипта, который помогает очистить конфигурационные таблицы в базе данных и вернуть ее к работоспособному состоянию. Внимание! Перед выполнением этих операций обязательно сделайте резервную копию базы данных средствами СУБД!


-- Очищаем таблицу незавершенных сохранений конфигурации
TRUNCATE TABLE configsave;

-- Удаляем маркеры незавершенных транзакций динамического обновления
DELETE FROM config WHERE FileName = 'commit';
DELETE FROM config WHERE FileName = 'dbStruFinal';
DELETE FROM config WHERE FileName = 'dynamicCommit';

После выполнения данных SQL-запросов база данных вернется к стабильному состоянию, соответствующему последнему успешно примененному демоническому обновлению.

Правильная методология разработки: как навсегда забыть об этой проблеме

Чтобы избежать подобных коллизий при командной разработке, необходимо пересмотреть подход к организации процесса разработки и обновлений.

  1. Полный отказ от динамического обновления на базах разработки.

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

  2. Разделение контуров разработки и эксплуатации.

    Рабочая база данных (продакшн) ни в коем случае не должна быть напрямую подключена к хранилищу конфигурации с возможностью редактирования объектов прямо в ней. Схема работы должна быть следующей:

    • Разработчики ведут работу исключительно в своих локальных (или выделенных тестовых) базах данных, подключенных к общему хранилищу.
    • Все изменения помещаются в хранилище конфигурации.
    • Из хранилища конфигурации собирается единый файл поставки или файл конфигурации (с расширением .cf).
    • Полученный файл конфигурации .cf накатывается на рабочую базу данных через процедуру «Сравнить, объединить с конфигурацией из файла» или «Загрузить конфигурацию из файла».
  3. Обязательное принудительное получение изменений перед захватом.

    Перед тем как осуществить захват любого объекта в работу, программист должен принудительно выполнить команду меню Конфигурация – Хранилище конфигурации – Обновить конфигурацию из хранилища. Не стоит полагаться на автоматический захват из контекстного меню конкретного объекта.

  4. Перезапуск Конфигуратора принудительно.

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

Соблюдение этих простых правил разработки и своевременный отказ от динамического обновления в процессе редактирования объектов из хранилища позволят вашей команде избежать потери ценного программного кода и обеспечат стабильную работу платформы «1С:Предприятие 8.3» на любой СУБД.

← На главную