Как исправить ошибку «Операция не может быть выполнена из-за несоответствия версии» при обмене через COM-соединение в 1С?

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

При настройке регулярного обмена данными (например, раз в 5 минут через регламентное задание и COM-соединение) разработчики часто сталкиваются со следующей ошибкой в модуле Обработка.ОбменДаннымиXML:

«Ошибка при вызове метода контекста (Записать): Операция не может быть выполнена из-за несоответствия версии или отсутствия записи базы данных (возможно, запись была изменена или удалена)!»

Разберем причины возникновения этой ситуации и проанализируем практические способы её устранения.

Выясним причину ошибки

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

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

Способ 1. Использование явных объектных блокировок

Рассмотрим вариант с проверкой доступности объекта перед его изменением и записью. Если объект удерживается или редактируется другим сеансом, можно попытаться наложить явную блокировку через метод Заблокировать() внутри блока Попытка ... Исключение.

Посмотрим на пример реализации блокировки объекта перед его модификацией:


Попытка
    ДокументОбъект.Заблокировать();
Исключение
    // Объект заблокирован другим пользователем или сеансом
    ВызватьИсключение "Не удалось заблокировать объект для записи: " + ОписаниеОшибки();
КонецПопытки;

Если метод Заблокировать() вызывает исключение, значит, пользователь в данный момент работает с объектом. В таком случае запись пропускается до следующего сеанса обмена.

Способ 2. Пропуск конфликтных объектов и оптимизация транзакций

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

  1. Разбиение обмена на порции или отдельные транзакции: записываем каждый объект (или небольшие группы объектов) в отдельной транзакции.
  2. Изоляция ошибок: при возникновении исключения несоответствия версии выполним ОтменитьТранзакцию() только для текущего объекта.
  3. Повторный попытка или пропуск: сбойный объект пропускается и остаётся на плане обмена, чтобы быть переданным при следующем запуске (через 5 минут), когда пользователь закроет форму.

Способ 3. Проверка объема мигрирующих данных

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

Убедимся в правильности настройки планов обмена:

← На главную