activiti - Завершить работу экземпляра запущенного процесса

У меня в Activiti запущен процесс, который состоит только из сервисных задач. Процесс длится долго, и в некоторых случаях я хотел бы завершить его на полпути. Процесс запущен с использованием

ProcessInstance pi = runtimeService.startProcessInstanceById(
                processDefinitionId, executionParameters);

На форуме activiti процессы можно прекращено вызовом

void deleteProcessInstance(String processInstanceId, String deleteReason);

on runtimeService.

Проблема в том, что метод startProcessInstanceById возвращается только после завершения выполнения. Так что я не получаю processInstance, если процесс не завершен.

Однако я отладил код и смог найти processInstanceId в реализации _ 7_.

Теперь, когда я вызываю runtimeService.deleteProcessInstance(processInstanceId, deleteReason) метод из другого потока, я получаю ActivitiObjectNotFoundException сообщение о том, что данный processInstanceId не существует.

Более того, когда processInstance запущен, вызов runtimeService.createProcessInstanceQuery().list() возвращает пустой список, даже если процесс запущен.


person ares    schedule 22.11.2016    source источник


Ответы (3)


void deleteProcessInstance(String processInstanceId, String deleteReason);

использует processInstanceId, который присутствует только в случае фиксации транзакции. (см. транзакции в activiti) Я не проверял, можно ли удалить запущенные в данный момент экземпляр процесса, но я бы ожидал там какого-то исключения (запущенный экземпляр процесса ссылается на удаленное выполнение)

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

person Martin Grofčík    schedule 23.11.2016
comment
Здесь у Мартина есть правильный ответ. Используйте обработчик синтаксического анализа, чтобы автоматически добавлять прослушиватель к каждой задаче службы, которая завершает работу экземпляра на границе активности (либо при завершении, либо при создании событий). Вы не сможете использовать REST API или стандартный экземпляр процесса Java для прерывания или удаления вызовов, так как вы никогда не попадете в базу данных с помощью своего сквозного процесса. - person Greg Harley; 23.11.2016

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

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

Я не уверен, что в этом случае deleteProcess действительно всегда будет удалять процесс, есть возможность столкнуться с исключениями блокировки db. Но вы можете выполнять всю работу в подпроцессе с ограничивающим прерыванием signalCatchingEvent, которое, вероятно, мгновенно отменит ваш процесс.

person Alexander Anikin    schedule 22.11.2016

Чтобы сгенерировать идентификатор экземпляра процесса после запуска, используйте этот код при выполнении скрипта:

forceUpdate();
person Nima Majdara    schedule 25.06.2019