cancel
Showing results for 
Search instead for 
Did you mean: 

Service tasks in parallel executed multiple times

osaxdelta
Champ on-the-rise
Champ on-the-rise

I am trying to use my service tasks in parallel. By research, I learnt that to use servicetasks in parallel, I need to make changes such as async=true and exlusive= false. After these changes, I managed to execute my service tasks in parallel but what I recognized now is, randomly, some service tasks get executed multiple times. For example, I created two service tasks in parallel whose jobs are only System.out.println("first") and System.out.println("second"). When I run this process and observe the outputs, there are sometimes two first-one second or one first-two second etc. What am i missing in here?

1 ACCEPTED ANSWER

I will present a solution that is compatible with only your use case.
It is not a general-purpose solution.

> Some of our service tasks might be 10 or more hours long.
> So, retrying service task that have already done will be disastrous

You can shift the element to retry.
Please place the element that doesn't wait like service task or non throwing event after each your service tasks(long time processing).And, you must set the element async=true.

If so, your service tasks(long time processing) will not retry and the additional element may retry.

View answer in original post

8 REPLIES 8

ryandawson
Elite Collaborator
Elite Collaborator

Could you post what your bpmn is and the content of your service tasks?

I'm thinking maybe you mean something that fits one of the examples under these engine tests - Activiti/MultiInstanceTest.java at develop · Activiti/Activiti · GitHub  which use BPMN from Activiti/activiti-engine/src/test/resources/org/activiti/engine/test/bpmn/multiinstance at develop ·... . But Possibly you mean something different.

After reading Daisuke's reply below I'm pretty sure that I misinterpreted and you mean processing of different service tasks in parallel, not multiple instances executing the same service logic as I had first thought. My apologies, Daisuke's reply is much more useful Smiley Happy

Yes I meant service tasks in parallel. Sorry I did not make it so clear. Thank you anyways Smiley Happy

daisuke-yoshimo
Star Collaborator
Star Collaborator

> async=true and exlusive= false

In parallel, if you make the above settings for each of the two service tasks, they are executed simultaneously on each asynchronous thread.
And if you place a parallel gateway after the service task and join it, you should get an exclusive error trying to update the process instance entity at the same time.

(ex) ProcessInstance[15001] was updated by another transaction concurrently

If you get an exclusive error, the asynchronous service task should retry.

And, if you place a activity that wait a action like user task, you shouldn't get an exclusive error.

For detail, please check the following document.
https://www.activiti.org/userguide/#exclusiveJobs

In our current application, our service tasks are only used to send http rest request to other services. So, I am afraid using user tasks after service task for wait action is not an option. In other words, our processes will consist only service tasks and they are automated. There won't be any user interaction after running the process( Some of our service tasks might be 10 or more hours long. So, retrying service task that have already done will be disastrous ) Is there any other solution like increasing database thread-pool capacity or disabling database update etc.?

Seems to me one path available is to create a reproducer test case and see if this is a bug in the engine. The closest I could find to an existing test is Activiti/ParallelGatewayTest.java at develop · Activiti/Activiti · GitHub  which uses Activiti/ParallelGatewayTest.testAsyncBehavior.bpmn20.xml at develop · Activiti/Activiti · GitHub . But it's not service tasks, I didn't find an example of that (I searched the codebase for activiti:async="true" activiti:exclusive="false"). Another path, and perhaps you can try both, might be to set a process variable specific for each of your parallel service tasks when they get run so that you know when it has been invoked and can hopefully use the variable to stop it from being run a second time if it has already completed correctly. I am speculating but it could be that in this instance your service tasks are completing adequately for your purposes but getting retried because the Activiti thinks that one might have failed. (Another path might be to set exclusive=true but presumably you don't want to do that as you're looking for the performance gain of running these tasks in parallel.)

I will present a solution that is compatible with only your use case.
It is not a general-purpose solution.

> Some of our service tasks might be 10 or more hours long.
> So, retrying service task that have already done will be disastrous

You can shift the element to retry.
Please place the element that doesn't wait like service task or non throwing event after each your service tasks(long time processing).And, you must set the element async=true.

If so, your service tasks(long time processing) will not retry and the additional element may retry.

Thank you very much!!!! This approach was very useful to us!