При разработке на платформе 1С:Предприятие 8.3 мы часто сталкиваемся с необходимостью изменения данных одного документа в процессе проведения или записи другого. Однако при использовании методов ЗаблокироватьДанныеДляРедактирования() и РазблокироватьДанныеДляРедактирования() могут возникать неожиданные ошибки блокировки. Давайте детально разберем, почему это происходит и как правильно проектировать подобные механизмы.
Для начала важно разграничить два типа защиты данных, которые часто путают:
ЗаблокироватьДанныеДляРедактирования(). Они принудительно запрещают другим пользователям редактировать запись до момента завершения вашего алгоритма.Основная проблема в вашем случае заключается в том, что когда пользователь открывает форму «Заказа покупателя» и редактирует его, он создает в памяти клиента «образ» документа. Если параллельно ваш фоновый процесс (или вызов с сервера из «Заказа поставщику») пытается заблокировать и записать этот же объект, возникает конфликт версий.
Рассмотрим сценарий возникновения конфликта по шагам:
ЗаблокироватьДанныеДляРедактирования() и записывает изменения в «Заказ покупателя». Версия в базе меняется на (Версия_2).Прямое изменение одних документов из других является не лучшей практикой разработки, так как это создает жесткие зависимости и блокировки. Рассмотрим более надежные способы реализации данной задачи.
Вместо того чтобы хранить ДатаДоставки как реквизит самого документа «Заказ покупателя», вынесите это значение в независимый Регистр сведений. Это позволит:
Если вам все же необходимо изменять сам документ, проанализируйте, действительно ли вам нужна ЗаблокироватьДанныеДляРедактирования(). Часто достаточно просто правильно построить транзакцию и использовать БлокировкаДанных (объект платформы для работы с блокировками на уровне СУБД).
Пример корректного использования блокировки для записи данных:
// Создаем объект блокировки
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("Документ.ЗаказПокупателя");
ЭлементБлокировки.Значение = СсылкаНаЗаказ;
ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
НачатьТранзакцию();
Попытка
Блокировка.Заблокировать();
ОбъектДокумента = СсылкаНаЗаказ.ПолучитьОбъект();
ОбъектДокумента.ОжидаемаяДатаВручения = НоваяДата;
ОбъектДокумента.Записать();
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
Разберем основные правила, которые помогут вам избежать подобных проблем в будущем:
Оповестить() после записи данных. В модуле формы «Заказа покупателя» в процедуре ОбработкаОповещения() вы сможете корректно обновить содержимое формы, не вызывая конфликта версий.Надеемся, данный разбор помог вам разобраться в механизмах платформы 1С и выбрать оптимальный путь для реализации вашей задачи!