I have been working with 5.18 and found issues when Activiti is under heavy load. I have a timer that may be triggered immediately (i.e. duration = PT0S). Apologies, I cannot provide the BPMN, but from the logs I have been able to observe the following:
The job executor will attempt to complete its transaction, which involves deleting an unused timer that has a due date of now. In this time frame the acquire jobs thread will lock the timer job and increase the REV_ (for example from 2 to 3) because the timer's due date is less than or equal to now. When the job executor attempts to delete the timer as part of normal cleanup (within milliseconds after the lock), the delete SQL statement it attempts will delete using the ID and REV_ = 2. The delete will fail because it was just locked and made REV_ = 3 milliseconds before. This leads the job executor to throw an ActivitiOptimisticLockingException.
My question is: is there a way to have the acquire jobs not mess with jobs that may currently about to be deleted or not alter the REV_ number upon locking? Are there strategies to avoid this from happening (i.e. is it required to give it a due date of PT1S at least)? I'm a little worried about the acquire jobs thread because I have found mysterious ActivitiOptimisticLockingExceptions pop up at random times with a job executor thread of only 1. This is the only time I have been able to truly debug what happened. The only possible culprit I can think of in these cases is the acquire jobs thread.
You've been heard, and actually there's another post about something similar that we're looking into. I need to look into this a bit further; if you have a minimalistic reproduction, that would help a lot.
In 2013, one of the Activiti gurus commented on this same issue saying that: "This exception will only happen if you have multiple Activiti Engines with the job executor activated." Can you verify that this isn't the case?