Почему дублируется номер документа в 1С при включенном контроле уникальности?

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

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

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

Влияние свойства ОбменДанными.Загрузка на контроль уникальности

Основная причина, по которой платформа 1С сознательно «закрывает глаза» на дублирование номеров и кодов — это использование специального механизма обмена данными. Проанализируем, как ведет себя система при записи объектов.

У каждого прикладного объекта (будь то документ или справочник) существует программное свойство ОбменДанными, содержащее свойство Загрузка. Когда это свойство принимает значение Истина, платформа переходит в особый режим работы. Он предназначен для того, чтобы беспрепятственно переносить информацию, созданную в других информационных системах или узлах распределенной базы.

При установке флага ОбменДанными.Загрузка = Истина платформа принудительно отключает следующие механизмы контроля:

Рассмотрим классический пример кода в модуле документа, который предотвращает выполнение лишних проверок при загрузке данных:


Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    
    // Если документ записывается в режиме обмена, прерываем выполнение логики
    Если ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;
    
    // Здесь располагаются проверки заполнения и другие бизнес-правила
    Если Не ЗначениеЗаполнено(Контрагент) Тогда
        ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Заполните контрагента!");
        Отказ = Истина;
    КонецЕсли;

КонецПроцедуры

Таким образом, если документ записывается программно с установленным флагом загрузки, платформа безусловно сохраняет его в СУБД, даже если его номер полностью дублирует уже существующий в системе.

Механизм возникновения дублей в распределенных базах (РИБ)

Выясним, как именно распределенная структура приводит к появлению одинаковых номеров документов на практике, если архитектура решения не была настроена должным образом. Представим работу крупной торговой компании, у которой есть центральный офис (Центральная база) и удаленный склад (Периферийная база). Между ними настроен УРИБ (Универсальный ресурс распределенных информационных баз).

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

  1. В Центральной базе менеджер создает документ «Реализация товаров и услуг». Система находит последний номер в базе и присваивает новому документу очередной свободный номер, например, 0000-000025.
  2. В этот же момент времени (до запуска очередного сеанса синхронизации) кладовщик на удаленном складе в локальной периферийной базе тоже создает документ «Реализация товаров и услуг». Локальная база ничего не знает о действиях менеджера в центре, поэтому ее система автонумерации находит свой последний номер и выдает тот же свободный номер — 0000-000025.
  3. Наступает время регламентного обмена. Данные выгружаются в XML-пакеты и отправляются навстречу друг другу.
  4. Во время чтения сообщения обмена в Центральной базе создается новый документ, пришедший со склада. Поскольку запись идет в режиме ОбменДанными.Загрузка = Истина, платформа не проверяет уникальность и успешно сохраняет документ со склада с номером 0000-000025. В этот же момент аналогичный процесс происходит в периферийной базе.

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

Решение проблемы с помощью префиксации номеров

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

Префикс — это короткий буквенный или цифровой код (обычно длиной от 2 до 4 символов), который добавляется платформой к началу любого создаваемого номера или кода. Например, для центрального офиса задается префикс ЦБ, а для удаленного склада — префикс СК.

При использовании префиксов сценарий автонумерации меняется:

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

Другие причины дублирования номеров в 1С

Помимо очевидной работы механизмов обмена данными в РИБ, в практической деятельности программистов и системных администраторов встречаются и иные источники проблем с уникальностью номеров.

1. Ручное вмешательство пользователей в нумерацию

Это наиболее распространенный человеческий фактор. Если у пользователя есть права на редактирование номеров документов, он может вручную изменить номер, случайно нарушив шаблон автонумерации. Например, если шаблон по умолчанию выглядит как АА00-000001, а пользователь вручную записывает документ с номером АА00-1 (убрав ведущие нули), механизм генерации номеров платформы сбивается.

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

2. Программное создание документов внешними обработками

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


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

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

3. Транзакционные сбои и конкурентный доступ

Проанализируем ситуацию, когда несколько пользователей одновременно проводят ресурсоемкие операции или работают в транзакциях. В СУБД механизмы блокировок защищают данные от искажения. Однако, если одна транзакция заблокировала таблицу номеров, создала документ и зарезервировала за собой номер, но еще не зафиксировала изменения в СУБД, параллельный процесс другого пользователя может запросить следующий номер.

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

4. Сбой кэширования и некорректное администрирование СУБД

Крайне опасной технической ошибкой является одновременное подключение двух разных кластеров серверов «1С:Предприятие» к одной и той же базе данных на уровне СУБД (MS SQL, PostgreSQL). Каждый сервер приложений кэширует пул номеров для ускорения работы пользователей. При работе двух независимых кластеров с одной СУБД кэширование полностью ломается, что неизбежно приводит к массовому перекрестному затиранию данных и генерации одинаковых номеров документов.

Как исправить дублирование номеров?

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

  1. Выявление дубликатов. Напишите простой запрос к таблице документов с группировкой по полю Номер и условием КОЛИЧЕСТВО(Ссылка) > 1. Это позволит быстро локализовать все проблемные документы.
  2. Восстановление уникальности. С помощью групповой обработки реквизитов или написанной внешней обработки переименуйте дублирующиеся номера (например, добавьте в конец номера символ или букву, чтобы сделать строку уникальной).
  3. Настройка префиксов. Если проблема возникла из-за РИБ, незамедлительно настройте префиксы для всех узлов обмена в справочнике «Префиксы информационных баз» или настройках синхронизации данных.
  4. Восстановление автонумерации. Если автонумерация сбилась из-за ручного ввода, воспользуйтесь стандартной обработкой «Установка порядка нумерации документов» или программно перенумеруйте документы с начала года, вернув им корректный формат с ведущими нулями.
← На главную