Hi Adrian!
>when a task is defined as async and is run, it adds an entry in act_ru_execution and act_ru_job.
Yes, but if you use asyncExecutor, it also puts this job into memory queue to reduce DB queries count for next step.
>Then a thread from a pool picks it up and "locks" it by updating LOCK_TIME_ and DUEDATE_ ?
Well, nearly… May be not thread from pool (I belive it's asyncExecutor main thread). And LOCK_TIME_ is set to current time, not to lock end. Also if it's exclusive job, process instance is locked similar to job lock. Note that here lock transaction is commited, that is update to lock time is put into DB immediately.
In case of several executors there are possible "normal" locking exceptions when they concurrently try to commit updated lock time. Winner locks job (and process), losers fall back and do other jobs.
>And if the task does not complete in that time it releases the lock (update again) so another thread can pick it up and start again ?
Well, nearly… Executor checks for LOCK_TIME_+asyncExecutorAsyncJobLockTimeInMillis comparing it to current time. If job is fetched from DB and got to execution, it's relocked, LOCK_TIME_ is undated.
>Why such behaviour
I'm not activiti developer, but logic is quite clear. Different activiti engines (in cluster, for example) do not communicate to each other, they can only synchronize through DB. It's possible to make sophisticated logic behind DB facade, but it's not transparent. So simple yet effective mechanics was used: commit lock time and check lock time + timeout.
There is no pings between engines that can tell other engines that current executor is still working on it. If your node takes job and loses intranet, power supply or simply sleeps for ages in web call, other nodes can still get this job… later.
>Basically I want to have the possibility to run either non async and async tasks only once until they finish / throw exception.
You can set asyncExecutorAsyncJobLockTimeInMillis and asyncExecutorTimedJobLockTimeInMillis to really high values (several days) and it will never happen again. You'll have to deal with jobs that were locked but never released though (for example, jobs running during server restart).