Почему возникает ошибка Несоответствие версии или отсутствие записи и как ее устранить

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

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

Механизм оптимистической блокировки

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

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

Скрытые причины изменения версии объекта

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

  1. Фоновые задания: Это самая частая причина в современных конфигурациях. Обмен с сайтом, синхронизация с мобильным приложением или регламентное обновление цен могут изменять номенклатуру в фоновом режиме. Даже если вы просто открыли карточку товара посмотреть описание, а в этот момент фоновый процесс обновил остаток на складе в этом же объекте — версия изменится.
  2. Подписки на события: Проанализируем цепочку событий. Вы записываете связанный объект (например, штрихкод или цену), а в системе настроена подписка на событие ПередЗаписью или ПриЗаписи, которая программно обращается к владельцу (номенклатуре) и обновляет в нем дату последнего изменения или служебный реквизит.
  3. Внешние HTTP/REST-сервисы (OData): Если база интегрирована с внешними системами через стандартный интерфейс OData, запись может производиться внешним скриптом. В журнале регистрации такие действия будут отображаться под учетной записью, используемой для интеграции.
  4. Режим ОбменДанными.Загрузка: Важно понимать, что установка свойства ОбменДанными.Загрузка = Истина отключает прикладные проверки в коде (в модулях объекта), но не отключает проверку версии самой платформой. Любая запись объекта в этом режиме всё равно инкрементирует версию в БД.

Диагностика через отладку фоновых заданий

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

  1. Убедимся, что на сервере 1С включен режим отладки (параметр -debug в строке запуска службы).
  2. В Конфигураторе перейдем в меню Отладка -> Настройка подключения.
  3. В появившемся окне нажмем кнопку Автоматическое подключение и установим флажок напротив пункта Фоновые задания.
  4. Теперь мы можем поставить точку останова в модуле объекта (например, в процедуре ПередЗаписью) или в модуле менеджера. Как только фоновое задание дойдет до этой строки, отладчик «поймает» его, и мы сможем просмотреть Стек вызовов, чтобы понять, какая именно процедура инициировала изменение.

Использование технологического журнала для поиска виновника

Бывают случаи, когда поймать момент записи отладчиком невозможно (например, на рабочем сервере под большой нагрузкой). Тогда на помощь приходит Технологический Журнал (ТЖ). Это самый мощный инструмент диагностики «невидимых» записей.

Настроим файл logcfg.xml так, чтобы он фиксировал все события записи в базу данных для конкретной таблицы. Нам нужно отслеживать события DBMSSQL (или DBV8DBEng для файловой базы). Пример настройки фильтра:


<event query="true">
    <eq property="Name" value="DBMSSQL"/>
    <like property="Sql" value="%REFERENCE123%"/> 
</event>

Здесь REFERENCE123 — это имя таблицы справочника в SQL (его можно узнать через функцию ПолучитьСтруктуруХраненияБазыДанных()). ТЖ покажет нам не только факт записи, но и полный контекст на языке 1С, включая фоновое задание и пользователя.

Программные способы решения проблемы

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

Рассмотрим пример кода, который позволяет перечитать объект при возникновении ошибки версии:


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

Управляемые блокировки как превентивная мера

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

Если мы хотим, чтобы фоновый обмен не мешал пользователю, мы можем в процедуре обмена перед записью накладывать управляемую блокировку на элемент. Если в этот момент пользователь уже нажал «Записать» в форме, обмен подождет. Однако помните: блокировка работает, только если она установлена в обоих конфликтующих процессах. Если в одном месте используется Заблокировать(), а в другом — нет, платформа не увидит конфликта до момента финальной проверки версии в СУБД.

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

← На главную