Нередко при развертывании резервной копии базы данных средствами СУБД (например, Microsoft SQL Server или PostgreSQL) разработчики и администраторы сталкиваются с неприятным поведением системы: при создании новых документов или элементов справочников платформа 1С присваивает им номера и коды, которые уже были заняты ранее. Создается впечатление, что счетчик автонумерации «застыл» во времени и генерирует дубли.
Разберем причины такого поведения платформы 1С:Предприятие и рассмотрим практические способы быстрого устранения ошибки.
Для оптимизации скорости генерации уникальных номеров и снижения транзакционных блокировок сервер 1С кэширует последние выданные номера объектов в оперативной памяти рабочего процесса rphost. При штатной работе база непрерывно инкрементирует этот внутренний счетчик.
Когда мы восстанавливаем бэкап в базу данных средствами СУБД в обход кластера 1С, рабочий процесс сервера не получает уведомления об изменении данных в таблицах. В результате rphost продолжает использовать старые закэшированные значения счетчиков или ориентируется на состояние базы до восстановления. Чтобы восстановить корректный порядок, необходимо заставить сервер пересчитать максимальные номера по фактическим записям в таблицах СУБД.
Самый быстрый и эффективный способ исправить нумерацию без остановки работы пользователей — вызвать встроенную процедуру глобального контекста ОбновитьНумерациюОбъектов(). Этот метод сбрасывает закэшированные значения в памяти сервера и рассчитывает новые значения на основании максимальных номеров, уже записанных в базе данных.
Если вызвать метод без параметров, платформа обновит нумераторы абсолютно для всех объектов конфигурации (документов, справочников, бизнес-процессов и задач):
// Обновление нумерации для всех объектов информационной базы
ОбновитьНумерациюОбъектов();
Этот код можно выполнить во внешней обработке, в консоли кода или в контексте сеанса с административными правами.
Если проблема затронула конкретный вид документов или справочников, мы можем передать в качестве параметра объект метаданных нужного типа:
// Обновление нумерации для конкретного типа документа
ОбновитьНумерациюОбъектов(Метаданные.Документы.РеализацияТоваровУслуг);
// Обновление нумерации для конкретного справочника
ОбновитьНумерациюОбъектов(Метаданные.Справочники.Номенклатура);
Также можно выполнить последовательный обход коллекций метаданных в цикле, если требуется выборочное обновление определенных разделов конфигурации:
Для Каждого ОбъектМетаданных Из Метаданные.Документы Цикл
ОбновитьНумерациюОбъектов(ОбъектМетаданных);
КонецЦикла;
Для Каждого ОбъектМетаданных Из Метаданные.Справочники Цикл
ОбновитьНумерациюОбъектов(ОбъектМетаданных);
КонецЦикла;
Поскольку закэшированные значения счетчиков хранятся в оперативной памяти процесса rphost, полная очистка кэша происходит при его перезапуске. Рассмотрим варианты выполнения этой процедуры:
1C:Enterprise 8.3 Server Agent (ragent) в оснастке служб операционной системы. При этом все процессы перезапускаются, а кэш нумераторов инициализируется заново при первом обращении к объектам.В редких случаях сбой генерации номеров проявляется не у всех пользователей, а только у конкретной учетной записи из-за повреждения локального кэша сеанса или сохраненных настроек автозаполнения форм. В такой ситуации помогает сброс настроек проблемного пользователя:
// Очистка настроек текущего пользователя информационной базы
ОчиститьНастройкиПользователя(ПользователиИнформационнойБазы.ТекущийПользователь());
ОбновитьНумерациюОбъектов() находит максимальный номер с помощью строкового сравнения. Если кто-то из пользователей вручную записал документ с нестандартной длиной номера, нарушил лидирующие нули или добавил посторонние символы (например, номер вида 999999 вместо 0000012345), автонумератор будет ориентироваться на ошибочную строку. Перед сбросом убедимся, что в базе нет документов с некорректными номерами.ОбновитьНумерациюОбъектов() сразу после команды RESTORE DATABASE.