Каждый администратор и разработчик систем на базе «1С:Предприятие 8», сталкивающийся с конфигурацией «1С:Документооборот», рано или поздно обнаруживает в журнале регистрации или на экранах пользователей неприятное диагностическое сообщение: «Операция не может быть выполнена из-за несоответствия версии или отсутствия записи базы данных (возможно, запись была изменена или удалена)!».
Особенно часто эта проблема проявляется при попытке выполнить задачу, запустить комплексный процесс или создать подзадачу. Пользователь заполняет форму, нажимает кнопку «Исполнено» или «Отправить», но вместо успешного завершения операции получает отказ платформы. Давайте подробно разберем природу этого явления, выясним истинные причины его возникновения и рассмотрим эффективные методы борьбы с ним.
Для начала проанализируем разницу между классическими блокировками СУБД (транзакционными/пессимистическими) и ошибкой несоответствия версий. Когда система сообщает о «несоответствии версии», мы имеем дело с механизмом оптимистической объектной блокировки, встроенным непосредственно в платформу «1С:Предприятие».
Рассмотрим по шагам стандартный жизненный цикл объекта при работе пользователя в интерфейсе:
ВерсияДанных (в СУБД это обычно поле типа timestamp или уникальный хэш версии). Допустим, считанная версия имеет условный номер "0001".Таким образом, оптимистическая блокировка — это защитный механизм платформы, предотвращающий потерю целостности данных. Ошибка сообщает о том, что «поезд ушел»: пока вы редактировали форму, данные в базе уже успели обновиться.
Почему же эта ошибка так часто возникает именно в «1С:Документооборот» (особенно версий 2.1)? Дело в архитектуре конфигурации, которая насыщена асинхронными процессами и фоновыми обработчиками. Проанализируем ключевые факторы риска:
Практика эксплуатации крупных внедрений «1С:Документооборот» показывает, что использование механизма «уведомлений окном» порождает колоссальное количество конфликтов оптимистических блокировок. Если пользователи часто держат такие окна открытыми, они неизбежно будут сталкиваться с описываемой ошибкой.
Рекомендуется полностью отключить всплывающие окна оповещений на рабочих столах пользователей и перевести систему на другие каналы информирования. Настроим альтернативные способы оповещения:
Если конфигурация доработана («допилена») и вызовы записи происходят в кастомных модулях, программисту необходимо переписать логику обновления объектов. Разберем по шагам, как правильно обходить конфликт оптимистической блокировки программным путем.
Основное правило: никогда не записывайте объект, если вы предварительно не перечитали его актуальную версию из базы данных непосредственно перед транзакцией записи, либо не наложили жесткую пессимистическую блокировку.
Рассмотрим пример правильного кода, минимизирующего возникновение конфликтов при программном изменении задач или процессов:
// Создаем объект блокировки для обеспечения монопольного доступа в транзакции
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("Задача.ЗадачаИсполнителя");
ЭлементБлокировки.УстановитьЗначение("Ссылка", СсылкаНаЗадачу);
ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
НачатьТранзакцию();
Попытка
// Накладываем управляемую транзакционную блокировку
Блокировка.Заблокировать();
// Получаем ОДНОЗНАЧНО актуальную версию объекта из СУБД внутри транзакции
ОбъектЗадачи = СсылкаНаЗадачу.ПолучитьОбъект();
Если ОбъектЗадачи <> Неопределено Тогда
// Выполняем требуемые изменения реквизитов
ОбъектЗадачи.Выполнена = Истина;
ОбъектЗадачи.РезультатВыполнения = "Задача успешно завершена в транзакции";
// Записываем объект. Ошибки несоответствия версий не возникнет,
// так как мы заблокировали запись для других сеансов и перечитали данные.
ОбъектЗадачи.Записать();
КонецЕсли;
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ЗаписатьЛогОшибки(ОписаниеОшибки());
ВызватьИсключение;
КонецПопытки;
Если изменения производятся в форме, и нам нужно гарантировать, что форма отображает актуальные данные без перезапуска, используем метод Оповестить() для уведомления всех открытых окон системы об изменении объекта, чтобы они вовремя вызвали процедуру обновления формы (ЭтаФорма.Прочитать()).
Если вы постоянно сталкиваетесь с ошибкой «Запись изменена другим пользователем», проанализируйте расписание регламентных заданий. Очень часто администраторы настраивают слишком высокую частоту выполнения ресурсоемких заданий, например:
Такая чрезмерная частота приводит к тому, что фоновые процессы непрерывно «дергают» объекты базы данных, обновляя их реквизиты и версии прямо под курсором мыши работающего пользователя. Увеличьте интервалы запуска регламентных заданий до разумных пределов (например, до 30 или 60 секунд), чтобы дать пользователям физическую возможность спокойно завершить и сохранить свои интерактивные действия.
Иногда корни проблемы кроются в платформенных багах кэширования метаданных и версий объектов. Версии платформы линейки 8.3.10 и ранние релизы 2.1 конфигурации «1С:Документооборот» содержали ряд зарегистрированных ошибок, при которых платформа ложно рапортовала об изменении версии данных (особенно при интенсивной работе с СУБД MS SQL).
Рекомендуется выполнить следующие шаги обновления:
Применяя комплексный подход — отключая избыточные всплывающие окна на клиентах, оптимизируя код работы с объектами в транзакциях и настраивая регламентные задания — мы сможем свести количество ошибок несоответствия версий к нулю и обеспечить комфортную и быструю работу пользователей в системе электронного документооборота.