Активност - Как да синхронизирам потребителска задача

Имам поток Activiti, който има секция User Task, която изглежда така:

Flow Screen

Основната идея е, че потребителската задача "Изчакайте известие" чака отговор от специалната опашка. Но всъщност конкретен код просто се състезава със задачата:

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