Hi meyerd,
I understand what you mean,
A and B are parallel executions, C is the parent, it is process instance,
so after A runs the last service task on its branch, the activity will be updated to join activity, and the version of C will be increased.
then B runs the last service task on its branch, Activiti engine will get the latest A and C from DB for B, so B and C will be deleted, and the activity in C will be updated to next activity just right after the join activity, when both A and B will update C, the ActivitiOptimisticLockingException occurs, that is the case.
In general, there is no problem, but we may forget one thing, if in the last service task of B, runs following code piece
public void execute(DelegateExecution execution) throws Exception {
ExecutionEntity executionEntity = (ExecutionEntity) execution;
Map<String, Object> variables = execution.getVariables();
}
since we want to get all the variables including the variables from process instance C, so the execution C object will be got from DB and put to cache at this time, so that after B completes the run of last service task, it will not query C from DB again, instead, it will get it from cache, but the C has been updated by A, so that is the conflict.