Activiti - Как синхронизировать пользовательскую задачу

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

Экран потока

Основная идея состоит в том, что пользовательская задача «Ждать уведомления» ожидает ответа из специальной Очереди. Но на самом деле конкретный код просто выполняет задачу:

Map<String, Object> variables = new HashMap<String, Object>();
variables.put("KEY", variable);

String assignee = variable.getAssignee();
processService.completeTask(assignee, variables);

Итак, моя проблема в том, что служба, отвечающая за этот код, может получать несколько ответов из этой очереди. Какого именно поведения я хочу (очередь может возвращать что-то вроде Message_Processed и через несколько миллисекунд возвращать Message_Send). Но когда приходит второй ответ, Activiti Engine выдает исключение (см. Причину), и весь поток умирает.

Caused by: org.activiti.engine.ActivitiOptimisticLockingException: Task[id=3867, name=Wait for Notification] was updated by another transaction concurrently

Итак, что я ищу: есть ли способ сделать задачу, каким-то образом, чтобы она принимала и проглатывала все ответы, не вызывая исключения.


person Serj Lotutovici    schedule 20.02.2014    source источник


Ответы (1)


Я вижу следующие моменты:

1) Возможно, вы захотите проверить задачу получения Activiti. На самом деле лучше дождаться сигнала о продолжении: http://www.activiti.org/userguide/index.html#bpmnReceiveTask

2) Вы, вероятно, получаете исключение OptimisticLockingException, потому что ваши обновления приходят «слишком быстро» и одновременно. Здесь я вижу варианты

  • что вы настраиваете своего потребителя очереди таким образом, чтобы он мог получать сообщения из очереди только в однопоточном режиме. Затем вы должны также убедиться, что ваша последующая служебная задача «Update MessageVO», а также ваша задача получения не отмечены как async = true. Это гарантирует, что вы сигнализируете задаче приема о продолжении и в той же транзакции базы данных снова создадите новую задачу приема, готовую к обновлению в следующем сообщении.

  • что вы позволяете потребителю очереди «аварийно завершить работу» с оптимистичным исключением блокировки и убедитесь, что ваш транзакционный сеанс с производителем очереди откатывается или явно запрашивает повторную доставку, чтобы сообщение было повторно доставлено в соответствии с некоторой политикой повторной доставки.

3) Другая причина вашего OptimisticLockingException может заключаться в том, что вы кэшируете старую / обновленную задачу вместо того, чтобы запрашивать ее непосредственно перед сигналом о продолжении. всегда делайте это, чтобы не «повторно использовать» устаревшую задачу или объект выполнения.

person Martin Schimak    schedule 20.02.2014
comment
Спасибо за ваш ответ. К сожалению, 1 и 3 не подходят, просто протестировали их. Нет взгляда = (Сейчас мы пробуем 2.2), откат кажется хорошим решением, но я подумал, может быть, есть другой способ добиться этого. - person Serj Lotutovici; 20.02.2014
comment
1) на самом деле задумывался не как решение, а скорее как подсказка использовать его вместо пользовательской задачи - в любом случае и для каждого решения, которое вы придумаете в конце! удачи!-) - person Martin Schimak; 20.02.2014