Task claim - spring - two users get the same task

I wonder if this is a potential bug:

we have a rest controller that searches for unassigned tasks, gets the first one, claims it and returns the form url to the browser. So users work in a batch mode, after task completion, they get the next task automatically.

Now we get bug reports that a task is shown to two users at the same time.
I inspected the code and saw that in the ClaimTaskCmd#execute() the following is done:

 TaskEntity task = taskManager.findTaskById(taskId);
    ensureNotNull("Cannot find task with id " + taskId, "task", task);

    checkClaimTask(task, commandContext);

    if (userId != null) { 
      if (task.getAssignee() != null) {
        if (!task.getAssignee().equals(userId)) {
          // When the task is already claimed by another user, throw exception. Otherwise, ignore
          // this, post-conditions of method already met.
          throw new TaskAlreadyClaimedException(task.getId(), task.getAssignee());
      } else {
    } else {
      // Task should be assigned to no one

If I do two claims simultaniously the condition check will allow the operation for both users since they both read the entity before it was claimed by the other user. I do not find any other checks later in the code.

Question: did you encounter the problem already? is this a bug/support issue? Is there something strange going on between mybatis and spring transactional behaviour? What would be a possible workaround?

Thanks a lot

Hi Jan,

There may be a problem, but I don’t think what you found is the reason. In this case, two engine commands try to update the same entry in ACT_RU_TASK in parallel. One of them is expected to fail with an OptimisticLockingException when it flushes its changes to the database.

Things you could check:

  • Make sure the OptimisticLockingException is not swallowed
  • Tune up the logging. Useful loggers in this case could be: org.camunda.bpm.engine.cmd to see when an engine command begins and ends. org.camunda.bpm.engine.impl.persistence.entity to see all executed SQL statements, their parameters and results. Set both of them to DEBUG for useful output.