Synchronization issue in parallel multi-instance call activity


When using a multi-instance call activity to iterate over a collection in parallel, it is possible for two or more threads to update the nrOfCompletedInstances and nrOfActiveInstances variables at the same time. This leaves the variables with wrong values.

The following lines are from Activiti's debug logs:

As can be seen, two threads try to update the variables at nearly the same time and the second one sets wrong values for them. Instead of setting 2 for nrOfCompletedInstances and 6 for nrOfActiveInstances, it sets 1 and 7, respectively.

This leads to some weird behavior. For example, if the collection that we're iterating over contains the numbers from 1 to 8, and each call activity prints one of these numbers, the output should be similar to:
1 2 3 4 5 6 7 8 (the order would probably be different due to the parallel execution)

However, because of the issue mentioned above, the result is:
2 1 3 4 5 6 7 8 1 4 4 (note the extra numbers)

The issue seems to be in the org.activiti.engine.impl.bpmn.behavior.ParallelMultiInstanceBehavior's leave() method. There, the values of nrOfCompletedInstances and nrOfActiveInstances are retrieved from the execution, incremented (or decremented) and then set back into the execution. These two operations are not in a synchronized block, however, nor are they in a separate DB transaction. This probably leads to the following situation:

1) Thread 1 retrieves the variables and they have values: nrOfCompletedInstances = 0, nrOfActiveInstances = 8.
2) Thread 2 retrieves the variables, before Thread 1 updates them and they have the same values: nrOfCompletedInstances = 0, nrOfActiveInstances = 8.
3) Both of them modify the variables independently, resulting in the values: nrOfCompletedInstances = 1, nrOfActiveInstances = 7.
4) Both of them attempt to set them back into the execution with these wrong values.

For more information, see this forum thread:







Alexander Tsvetkov