Ошибка «Данные были изменены или удалены другим пользователем» в 1С означает, что объект, который вы пытаетесь записать, уже успел записать кто-то другой: коллега, фоновое задание или обмен. Платформа сравнивает версию данных в форме и в базе и отменяет запись, чтобы не затереть чужие изменения. Избежать потери работы можно двумя приемами: занимать объект блокировкой при открытии формы и не менять «живые» объекты из обработок напрямую, а пропускать их через очередь.
Разберем, откуда берется конфликт, как устроены блокировки и какой код я ставлю в формы и обработки, где такие конфликты регулярно случаются.
Откуда берется конфликт
Типичная история: пользователь А открыл документ и полчаса его заполнял. Пользователь Б открыл тот же документ, поправил одно поле и записал. Пользователь А нажимает «Записать» — и получает ошибку. Работу приходится повторять.
Вторая частая причина — программные изменения: регламентное задание перепроводит документы, обмен загружает изменения, обработка массово правит реквизит. Пользователь в этот момент держит документ открытым и при записи получает тот же отказ.
Какие блокировки есть в платформе
| Механизм | Как работает | Когда срабатывает |
|---|---|---|
| Оптимистическая блокировка (версия данных) | При записи сверяется ВерсияДанных объекта | Всегда при записи объекта |
| Объектная пессимистическая блокировка | ЗаблокироватьДанныеДляРедактирования запрещает другим сеансам блокировать и редактировать объект | В форме при начале редактирования, либо явно из кода |
| Управляемая (транзакционная) блокировка | БлокировкаДанных внутри транзакции | Для согласованного чтения и записи, например остатков при проведении |
Форма сама пытается занять объект, когда пользователь начинает его менять. Но если второй пользователь только открыл документ и еще ничего не трогал, а первый тем временем записал, конфликт обнаружится лишь при записи. А программный код, который получает объект через ПолучитьОбъект() и сразу пишет, пессимистическую блокировку вообще не ставит, если вы не сделали это сами.
Управляемые блокировки здесь не помогут: они живут только до конца транзакции и защищают данные от параллельных транзакций, а не от пользователя, который держит форму открытой.
Блокировка объекта при открытии формы
Если документ долго заполняется и конфликты бьют по людям, имеет смысл занимать его сразу при открытии. Второй пользователь увидит форму только для просмотра и сообщение о том, что документ занят.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ЗанятьОбъектДляРедактирования();
КонецПроцедуры
// Пытается заблокировать объект за этой формой. При неудаче переводит форму в режим просмотра.
&НаСервере
Процедура ЗанятьОбъектДляРедактирования()
Если Объект.Ссылка.Пустая() Тогда
Возврат;
КонецЕсли;
Попытка
ЗаблокироватьДанныеДляРедактирования(Объект.Ссылка, , УникальныйИдентификатор);
Исключение
ТолькоПросмотр = Истина;
ТекстСообщения = СтрШаблон(
НСтр("ru = 'Документ сейчас редактирует другой пользователь, он открыт только для просмотра.
|%1'"), КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
ОбщегоНазначения.СообщитьПользователю(ТекстСообщения);
КонецПопытки;
КонецПроцедурыТретий параметр — уникальный идентификатор формы. Блокировка привязывается к форме и снимается, когда форма закрывается. Если хотите освободить объект раньше (например, по кнопке «Освободить»), вызовите РазблокироватьДанныеДляРедактирования(Объект.Ссылка, УникальныйИдентификатор) в серверной процедуре.
Не делайте разблокировку серверным вызовом из ПриЗакрытии, если параметр ЗавершениеРаботы равен Истина: при завершении работы приложения серверные вызовы из этого обработчика запрещены.
Компромиссы подхода
- Пользователь, который просто открыл документ посмотреть, тоже его занимает. Для справочников и документов «на просмотр» это раздражает — применяйте прием там, где редактирование действительно долгое: заказы, сметы, сложные документы с табличными частями.
- Ошибка блокировки содержит сведения о том, кем занят объект; покажите их пользователю, чтобы он мог договориться с коллегой.
- Новый, еще не записанный объект блокировать нечего: проверка на пустую ссылку обязательна.
Программное изменение объектов: очередь вместо прямой записи
Обработки и регламентные задания должны уважать пользовательские блокировки. Надежная схема, которую я использую:
- Создать регистр сведений
ОчередьОбработкиДокументовс измерениемДокументи, при необходимости, ресурсами с параметрами обработки и датой постановки. - Обработчик-источник не меняет документ, а записывает его в очередь.
- Регламентное задание читает очередь, пытается заблокировать каждый документ, при успехе обрабатывает, записывает и снимает блокировку. Занятые документы остаются в очереди до следующего запуска.

// Обработчик регламентного задания: обрабатывает документы из очереди,
// пропуская те, что сейчас редактируют пользователи.
Процедура ОбработатьОчередьДокументов() Экспорт
ОбщегоНазначения.ПриНачалеВыполненияРегламентногоЗадания(Метаданные.РегламентныеЗадания.ОбработкаОчередиДокументов);
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 500
| Очередь.Документ КАК Документ
|ИЗ
| РегистрСведений.ОчередьОбработкиДокументов КАК Очередь
|УПОРЯДОЧИТЬ ПО
| Очередь.ДатаПостановки";
Выборка = Запрос.Выполнить().Выбрать();
Обработанные = Новый Массив;
Пока Выборка.Следующий() Цикл
Попытка
ЗаблокироватьДанныеДляРедактирования(Выборка.Документ);
Исключение
// Документ занят пользователем — вернемся к нему в следующий запуск.
Продолжить;
КонецПопытки;
Попытка
ДокументОбъект = Выборка.Документ.ПолучитьОбъект();
ЗаполнитьДокументПоОчереди(ДокументОбъект);
ДокументОбъект.Записать();
Обработанные.Добавить(Выборка.Документ);
Исключение
ЗаписьЖурналаРегистрации(НСтр("ru = 'Очередь обработки документов'"),
УровеньЖурналаРегистрации.Ошибка, , Выборка.Документ,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
// Снимаем блокировку при любом исходе обработки.
РазблокироватьДанныеДляРедактирования(Выборка.Документ);
КонецЦикла;
УдалитьИзОчереди(Обработанные);
КонецПроцедуры
Процедура УдалитьИзОчереди(Документы)
Для Каждого Документ Из Документы Цикл
НаборЗаписей = РегистрыСведений.ОчередьОбработкиДокументов.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Документ.Установить(Документ);
НаборЗаписей.Записать();
КонецЦикла;
КонецПроцедурыДетали, которые важны в продуктиве:
- Порция.
ПЕРВЫЕ 500ограничивает время одного запуска, чтобы задание не висело часами. - Ошибка обработки не теряет документ. Он остается в очереди, а причина пишется в журнал регистрации. Для документов, которые падают постоянно, добавьте счетчик попыток в ресурсы регистра.
- Блокировка снимается всегда, даже если запись упала. Иначе документ останется занятым до конца сеанса фонового задания.
- Очищаемая очередь — обычный регистр сведений, его легко мониторить простым отчетом: сколько документов ждет и как давно.
Если процедура выполняется без регламентного задания (например, в обработке), уберите вызов ПриНачалеВыполненияРегламентногоЗадания — это метод БСП именно для обработчиков регламентных заданий.
Как разбирать конфликты в существующей базе
Когда пользователи жалуются на ошибку записи, я иду по такому порядку:
- Журнал регистрации по проблемному документу: кто и что записал между открытием и попыткой записи. Часто это не человек, а обмен или регламентное задание.
- Список регламентных заданий и подписок на события, которые пишут объекты этого типа.
- Обработчики форм, которые записывают связанные объекты (например, при записи заказа перезаписывается договор, открытый у другого пользователя).
- По итогам — очередь для программных изменений и блокировка при открытии для «тяжелых» документов.
Типичные ошибки
- Блокировка без идентификатора формы в
ПриСозданииНаСервере: она живет до конца сеанса, и документ остается занятым после закрытия формы. - Нет проверки пустой ссылки — ошибка при открытии нового документа.
- В фоновом задании нет разблокировки в ветке ошибки.
- Попытка решить проблему управляемыми блокировками — они не защищают форму пользователя.
- Массовая обработка без очереди в рабочее время — десятки пользователей получают ошибку записи одновременно.
Если конфликты записи и ожидания на блокировках стали системными, это повод для аудита производительности: там же часто находятся и долгие транзакции. Точечные доработки форм и обработок делаю в рамках доработки 1С.
Итог
- Ошибка «Данные были изменены или удалены другим пользователем» — срабатывание оптимистической блокировки по версии данных.
ЗаблокироватьДанныеДляРедактированияс идентификатором формы занимает документ на время работы с ним.- Программные изменения пропускайте через очередь с регламентным заданием и блокировкой каждого объекта.
- Блокировку в фоновом коде снимайте при любом исходе, а занятые объекты оставляйте на следующий запуск.




