Как решить проблему с зависшими задачами в очереди выполнения 1С:Документооборота?

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

В процессе эксплуатации программного продукта 1С:Документооборот (особенно редакций 2.1 и 3.0) пользователи и администраторы часто сталкиваются со специфической проблемой. При попытке открыть задачу согласования, утверждения или исполнения на форме отображается предупреждение: «Задача находится в очереди для выполнения. Выполнение задачи произойдет автоматически в ближайшее время». При этом на форме полностью отсутствуют управляющие кнопки (например, «Согласовано», «Исполнено», «Отклонить»), и даже администратор системы не может продвинуть процесс дальше.

В этой статье мы подробно разберем, как устроен механизм фонового выполнения задач, проанализируем основные причины его сбоев и рассмотрим несколько практических способов решения этой проблемы — от простых интерактивных действий до написания корректирующих программных скриптов.

Как работает фоновое выполнение задач в 1С:Документообороте

Для снижения нагрузки на интерфейс пользователя и предотвращения длительных блокировок таблиц базы данных при записи сложных бизнес-процессов в системе применяется механизм отложенного выполнения. Рассмотрим эту цепочку событий по шагам:

  1. Когда пользователь нажимает кнопку выполнения задачи, система не проводит всю транзакцию мгновенно. Вместо этого в регистр сведений ЗадачиДляВыполнения (в версии 3.0 — в справочник Очередь заданий) помещается запись со статусом готовности.
  2. Специализированное регламентное задание «Фоновое выполнение задач» (в 3.0 — «Диспетчер обработки очереди заданий») регулярно считывает эти записи, запускает транзакцию на сервере, выполняет задачу и удаляет запись из очереди выполнения — для профилактики сбоев и зависаний пригодится программа автоматического контроля регламентных заданий в Telegram.
  3. Если во время работы регламентного задания происходит сбой (ошибка прав доступа, блокировка СУБД, ошибка в коде обработчиков), транзакция откатывается. Запись остается в очереди, но блокировка с интерфейса задачи не снимается. В итоге задача «зависает».

Давайте выясним основные причины возникновения подобных ситуаций и рассмотрим эффективные методы борьбы с ними.

Шаг 1. Диагностика через Журнал регистрации

Прежде чем предпринимать какие-либо действия, нам необходимо понять точную причину сбоя. Для этого проанализируем поведение системы с помощью системных логов — для этого есть автоматическое отслеживание ошибок в журнале регистрации.

Откроем Журнал регистрации и настроим отбор по следующим параметрам:

Внимательно изучим детальные записи об ошибках. Чаще всего здесь можно обнаружить падение транзакции на определенном обработчике (например, при попытке записи визы согласования РаботаСВизамиСогласования.Записать или проверке прав рабочих групп РаботаСРабочимиГруппами). Если ошибка вызвана правами доступа, то выполнение блокируется из-за того, что регламентное задание пытается завершить задачу от лица пользователя, у которого в данный момент урезаны права или установлена пометка удаления.

Решение 1. Очистка регистра «Задачи для выполнения» (Интерактивный метод)

Если зависших задач относительно немного (например, несколько исторических процессов), самый быстрый способ вернуть управление пользователям — очистить очередь блокировки напрямую.

Выполним следующие действия по шагам:

  1. Перейдем в меню «Функции для технического специалиста» (в старых версиях — «Все функции»).
  2. Найдем регистр сведений Задачи для выполнения (в ДО 3.0 ищем справочник Очередь заданий) — быстро очистить зависшие записи поможет обработка очистки и редактирования регистров сведений 1С.
  3. В открывшемся списке найдем записи, которые ссылаются на наши зависшие задачи. Ориентироваться можно по дате возникновения проблемы или по ссылке на саму задачу.
  4. Удалим эти записи из регистра. Важно понимать: при этом удаляется не сама задача или бизнес-процесс, а исключительно управляющая запись в очереди фоновой обработки.
  5. Откроем карточку задачи под учетной записью исполнителя или администратора. Мы увидим, что предупреждение об очереди исчезло, а стандартные кнопки управления («Согласовано», «Исполнено») снова стали доступными. Теперь мы можем выполнить задачу вручную.

Решение 2. Временное отключение фонового выполнения задач

Если в вашей системе регулярно происходят конфликты блокировок или пользователи жалуются на постоянное зависание кнопок, мы можем временно или на постоянной основе отключить асинхронный режим обработки. Это заставит систему выполнять все алгоритмы записи и проведения задач синхронно, непосредственно в момент нажатия кнопки пользователем.

Для этого выполним настройку в интерфейсе:

  1. Перейдем в раздел Настройка и администрирование -> Настройка программы -> Процессы и задачи.
  2. Найдем и снимем флажки с опций:
    • Использовать фоновый старт процессов
    • Использовать фоновое выполнение задач
  3. Сохраним настройки.

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

Решение 3. Устранение конфликтов узлов обмена (РИБ) после обновления базы

Очень распространенная техническая проблема возникает при переходе на новые релизы конфигурации (например, при обновлении с редакции 1.2/2.0 на 2.1 или при работе с базами, которые ранее участвовали в распределенном обмене РИБ).

Суть проблемы заключается в том, что регламентный обработчик задач жестко сверяет узел обмена бизнес-процесса с предопределенным элементом текущего узла (ЭтотУзел). Если после обновления или переноса данных идентификатор узла обмена у существующих бизнес-процессов заполнился некорректно (например, стал равен битому GUID или заполнился нулями 0000-0000...), регламентное задание просто игнорирует такие процессы, и задачи зависают в очереди навсегда — устранить подобные ошибки в регистрах поможет обработка удаления битых ссылок в регистрах 1С.

Для исправления этой ситуации мы можем использовать два программных метода.

Вариант А. Использование модифицированного обработчика выполнения задач

Рассмотрим код внешней обработки или расширения, которая временно подменяет стандартную выборку задач регламентного задания, игнорируя жесткую привязку к узлам обмена, и принудительно проталкивает все зависшие задачи:


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

Вариант Б. Групповое исправление узлов обмена в базе данных

Если в вашей базе накопилось множество процессов с неверно заполненными идентификаторами узлов обмена, правильнее будет исправить их один раз централизованно. Напишем и запустим обработку, которая найдет все записи с некорректным узлом обмена и перезапишет их значением по умолчанию:


&НаСервере
Процедура ИсправитьУзлыОбменаВБизнесПроцессах() Экспорт
    УстановитьПривилегированныйРежим(Истина);
    ЭтотУзелОбмена = РаботаСБизнесПроцессами.ЭтотУзелОбменаДляОбработкиПроцессов;
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	ДанныеБизнесПроцессов.БизнесПроцесс КАК БизнесПроцесс,
        |	ДанныеБизнесПроцессов.УзелОбмена КАК УзелОбмена
        |ИЗ
        |	РегистрСведений.ДанныеБизнесПроцессов КАК ДанныеБизнесПроцессов
        |ГДЕ
        |	НЕ ДанныеБизнесПроцессов.УзелОбмена = &УзелОбмена";
        
    Запрос.УстановитьПараметр("УзелОбмена", ЭтотУзелОбмена);
    РезультатЗапроса = Запрос.Выполнить();
    Выборка = РезультатЗапроса.Выбрать();
    
    Сообщить("Найдено процессов для исправления: " + Выборка.Количество());
    
    Пока Выборка.Следующий() Цикл
        БП = Выборка.БизнесПроцесс.ПолучитьОбъект();
        Если БП <> Неопределено Тогда
            // Записываем БЕЗ ОбменДанными.Загрузка = Истина, 
            // чтобы система корректно обновила связанные подчиненные регистры сведений!
            БП.УзелОбмена = ЭтотУзелОбмена;
            Попытка
                БП.Записать();
            Исключение
                Сообщить("Ошибка записи процесса " + БП.Ссылка + ": " + ОписаниеОшибки());
            КонецПопытки;
        КонецЕсли;
    КонецЦикла;
    Сообщить("Корректировка узлов обмена завершена успешно.");
КонецПроцедуры

Решение 4. Исправление пустого состояния бизнес-процесса

Еще одна скрытая причина, о которой редко пишут в официальной документации — пустое состояние процессов после перехода со старых редакций. В некоторых версиях ДО 2.1 в коде регламентных заданий присутствует фильтр, обрабатывающий только те процессы, у которых реквизит Состояние равен значению Активен.

Если в базе данных по какой-то причине это поле оказалось незаполненным, такие задачи также будут вечно ожидать обработки. Решается эта проблема написанием аналогичной групповой обработки, которая находит все активные (незавершенные) бизнес-процессы в регистре сведений ДанныеБизнесПроцессов с пустым состоянием и программно устанавливает значение Перечисление.СостоянияБизнесПроцессов.Активен.

Рекомендации по профилактике и администрированию

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

Применяя данные подходы, вы сможете оперативно восстановить работоспособность бизнес-процессов в компании и обеспечить стабильную и бесперебойную работу пользователей в системе «1С:Документооборот».

← На главную