Как найти источник дублирования записей в документе 1С с помощью стека вызовов?

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

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

Метод 1: Использование программного получения стека через исключения

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

Разберем, как это реализовать на практике:


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

Важно помнить, что полнота информации в ИнформацияОбОшибке() сильно зависит от версии платформы. Начиная с версии 8.3.19 и выше, платформа предоставляет значительно более детальную информацию о цепочке вызовов.

Метод 2: Настройка Технологического журнала (ТЖ)

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

  1. Откройте файл logcfg.xml на сервере 1С.
  2. Настройте фильтрацию по событию DBMSSQL для конкретной таблицы или имени объекта.
  3. Добавьте параметр StackTrace в настройки события, чтобы при каждом обращении к базе данных сервер записывал текущий стек вызовов.

Пример настройки фрагмента logcfg.xml:


<event-groups>
    <event-group name="DataChanges">
        <event>DBMSSQL</event>
        <property name="SQL"/>
        <property name="StackTrace"/>
    </event-group>
</event-groups>
<logs>
    <log location="..." history="24">
        <event-group name="DataChanges"/>
        <filter>
            <event>DBMSSQL</event>
            <sql>LIKE '%ИмяТаблицы%'</sql>
        </filter>
    </log>
</logs>

Этот метод позволит вам увидеть не только имя пользователя, но и точный стек вызовов (имя метода, модуль, номер строки), который отправил команду INSERT или UPDATE в базу данных.

Метод 3: Использование Дополнительных свойств объекта

В библиотеке БСП существует механизм ДополнительныеСвойства. Мы можем использовать его для маркировки данных. Если у вас есть подозрения на конкретные регламентные задания или внешние обработки, попробуйте проставить метку в начале их работы.

В коде обработки добавьте:


Объект.ДополнительныеСвойства.Вставить("ИсточникОбработки", "ИмяМоейОбработки");
// Далее код записи объекта
Объект.Записать();

Затем в ПередЗаписью вы сможете легко прочитать это свойство: Объект.ДополнительныеСвойства.Получить("ИсточникОбработки"). Если метка найдена — вы нашли источник дублей.

Рекомендации по анализу

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

← На главную