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