Как быстро откатить состояние данных в 1С при воспроизведении и локализации ошибок?

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

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

Способ 1. Выборочный ручной откат и очистка созданных объектов

Проанализируем простейший сценарий, когда в процессе воспроизведения ошибки было выполнено лишь небольшое количество изолированных действий. Если мы точно понимаем, какие именно объекты были изменены или созданы, самым быстрым решением будет отмена проведения созданных документов или их непосредственная пометка на удаление.

Однако этот подход имеет серьезные ограничения:

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

Поэтому ручная очистка допустима только для простых локальных тестов. В остальных ситуациях требуются платформенные и системные механизмы.

Способ 2. Выполнение тестируемого алгоритма в явной транзакции

Если для моделирования ошибки мы используем внешнюю обработку или запускаем алгоритм программно, наиболее удобным и чистым способом является изоляция работы в пределах транзакции базы данных. Рассмотрим пример реализации:


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

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

Способ 3. Моментальные снимки на уровне СУБД

Когда требуется полный интерактивный цикл работы пользователя, стандартная перезаливка базы средствами СУБД из резервной копии (файла бэкапа) отнимает слишком много времени. Вместо этого задействуем функционал моментальных снимков (Database Snapshots), работающих по технологии Copy-on-Write (копирование при записи).

  1. MS SQL Server: перед запуском теста создаем снимок базы данных через CREATE DATABASE ... AS SNAPSHOT OF .... Снимок создается практически мгновенно, поскольку изначально не содержит самих данных, а лишь фиксирует состояние страниц. После неудачного прогона выполняем команду восстановления (RESTORE DATABASE ... FROM DATABASE_SNAPSHOT). База мгновенно откатывается к начальному срезу без перестроения индексов.
  2. PostgreSQL: используем механизм создания баз данных из шаблона (TEMPLATE). Исходная база переводится в состояние шаблона, а для каждого нового цикла тестирования создается новая база с помощью директивы CREATE DATABASE test_db TEMPLATE master_test_db.
  3. Файловые системы с CoW (ZFS, Btrfs, LVM): если СУБД развернута на Linux, снимок файловой системы тома с базами данных создается за доли секунды и позволяет мгновенно заморозить и восстановить файлы данных.

Способ 4. Снапшоты виртуальной машины

Если тестовый контур развернут на отдельной виртуальной машине (например, в среде гипервизора VMware или Hyper-V), оптимальным решением будет создание моментального снимка (snapshot) всей виртуальной машины. В этом случае мы фиксируем не только файлы СУБД, но и состояние процессов сервера 1С, включая кэш кластера и открытые сетевые сеансы. Откат к снапшоту возвращает систему в исходную точку за считанные секунды и полностью исключает появление зависших соединений.

Способ 5. Использование разделения данных

В конфигурациях, поддерживающих механизм разделения данных платформы 1С:Предприятие (например, решения на базе Библиотеки стандартных подсистем), можно избежать перезаливки всей базы за счет создания отдельных областей данных. Мы настраиваем одну эталонную область данных, а для каждого сеанса отладки либо подключаемся к новой пустой области, либо создаем копию эталонной области. Данные при этом изолированы, а общие метаданные и системные таблицы не требуют переинициализации.

Важные технические правила при регулярном откате

Выясним причину частых сбоев при автоматическом восстановлении баз и сформулируем правила стабильной работы:

  1. Завершение сеансов перед восстановлением: сервер 1С держит постоянный пул открытых соединений к СУБД. При попытке восстановить снимок базы СУБД выдаст ошибку о занятости таблиц. Поэтому перед операцией отката необходимо программно заблокировать регламентные задания и принудительно отключить активные сеансы кластера 1С (например, через утилиту командной строки rac).
  2. Отказ от формата .dt для циклической отладки: регулярная выгрузка и загрузка файлов с расширением .dt крайне неэффективна для повторных тестов. Процесс загрузки файла .dt полностью пересоздает структуру таблиц СУБД, повторно строит индексы и пересчитывает итоги, что при базах объемом в десятки гигабайт занимает часы вместо секунд.
← На главную