OptimisticLockingException при слиянии токенов в параллельном гейте

Здравствуйте. Использую Camunda External Task 7.16.
Помогите, пожалуйста.

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

Такой случай явно даже описан в доке, но конкретики я не увидел, но непонятно с ним как борются.

Как я понимаю, корневая причина в том, что две таски, будучи выполненными примерно в одно и тоже время (плюс/минус миллисекунды) пытаются закомплититься и обновить переменные процесса. В этот момент срабатывает эта оптимистическая блокировка в одном из воркеров, построенная на версионировании. И никуда не деться, кроме как попытаться заретраить taskComplete() еще раз в том воркере, который получил ошибку. Правильно ли я понимаю суть ошибки? Может быть есть какие-то еще варианты?

TASK/CLIENT-01009 Exception while completing the external task: The corresponding process instance could not be resumed. Reason: status code: 500, reason phrase: {“type”:“OptimisticLockingException”,“message”:“ENGINE-03005 Execution of ‘UPDATE VariableInstanceEntity’ failed. Entity was updated by another transaction concurrently.”}

Вроде бы говорится о том, что оно должно быть повторено

И вот прямо мой случай нарисован в процессе. Только там вместо user task, - service task

Добрый день.

Попробуйте следующие варианты.

Используйте локальные переменные задачи

Разделите переменные для каждой ветки процесса.
Например, для двух параллельных задач:
Первый воркер обновляет переменную taskAResult.
После параллельного выполнения, используйте Script Task или Service Task, чтобы объединить результаты.

Автоматизируйте механизм ретрая в воркере, например, через задержку и повторный вызов.

boolean success = false;
while (!success) {
    try {
        externalTaskService.complete(externalTask, variables);
        success = true;
    } catch (OptimisticLockingException e) {
        Thread.sleep(100); 
    }
}

Конфигурация воркеров
Увеличьте lockDuration
Настройте количество ретраев: Вы можете увеличить количество повторных попыток обработки задачи при возникновении исключения.

1 лайк

Здравствуйте. Я уже попробовал свой taskComplete() обернуть @Retriable(). По идее, должно помочь. Пока тестируем.