I have created a User Task with 3 BoundaryTimerEvents:
1 non interruptive timer event with a period of 10s (R/PT10S)
1 non interruptive timer event with a duration of 30s (PT30S)
1 interruptive timer event with a duration of 1mn (PT1M)
Here’s the BPMN (6.6.0):
When I execute it, when the (last) interruptive timer after 1mn is executed, I have an OptimisticLockException which rollbacks this branch and returns to the User Task (script task asynchronous or not, I tested both with same result).
The result is that the User Task is still alive with the recurring 10s timer still alive also.
The expected result is obviously to finish the process…
I have tested with 6.7.0 and this behaviour doesn’t seem to appear (which doesn’t mean it isn’t here :)).
org.flowable.common.engine.api.FlowableOptimisticLockingException: Execution[ id ‘d5cff2a4-3c83-11ec-9040-c03eba3cd8b2’ ] - activity ‘sid-D4BCF135-67F9-4F21-8940-DD10FE6D2F03’ - parent ‘d5cff29c-3c83-11ec-9040-c03eba3cd8b2’ was updated by another transaction concurrently
at org.flowable.common.engine.impl.db.DbSqlSession.flushUpdates(DbSqlSession.java:577) ~[flowable-engine-common-6.6.1-SNAPSHOT.jar:6.6.1-SNAPSHOT]
at org.flowable.common.engine.impl.db.DbSqlSession.flush(DbSqlSession.java:364) ~[flowable-engine-common-6.6.1-SNAPSHOT.jar:6.6.1-SNAPSHOT]
at org.flowable.common.engine.impl.interceptor.CommandContext.flushSessions(CommandContext.java:211) ~[flowable-engine-common-6.6.1-SNAPSHOT.jar:6.6.1-SNAPSHOT]
at org.flowable.common.engine.impl.interceptor.CommandContext.close(CommandContext.java:69) ~[flowable-engine-common-6.6.1-SNAPSHOT.jar:6.6.1-SNAPSHOT]
at org.flowable.common.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:92) ~[flowable-engine-common-6.6.1-SNAPSHOT.jar:6.6.1-SNAPSHOT]
at org.flowable.common.spring.SpringTransactionInterceptor.lambda$execute$0(SpringTransactionInterceptor.java:57) ~[flowable-spring-common-6.6.1-SNAPSHOT.jar:6.6.1-SNAPSHOT]
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140) ~[spring-tx-5.2.12.RELEASE.jar:5.2.12.RELEASE]
at org.flowable.common.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:57) ~[flowable-spring-common-6.6.1-SNAPSHOT.jar:6.6.1-SNAPSHOT]
at org.flowable.common.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:30) ~[flowable-engine-common-6.6.1-SNAPSHOT.jar:6.6.1-SNAPSHOT]
at org.flowable.common.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:56) ~[flowable-engine-common-6.6.1-SNAPSHOT.jar:6.6.1-SNAPSHOT]
at org.flowable.common.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:51) ~[flowable-engine-common-6.6.1-SNAPSHOT.jar:6.6.1-SNAPSHOT]
at org.flowable.job.service.impl.asyncexecutor.ExecuteAsyncRunnable.executeJob(ExecuteAsyncRunnable.java:127) [flowable-job-service-6.6.1-SNAPSHOT.jar:6.6.1-SNAPSHOT]
at org.flowable.job.service.impl.asyncexecutor.ExecuteAsyncRunnable.run(ExecuteAsyncRunnable.java:115) [flowable-job-service-6.6.1-SNAPSHOT.jar:6.6.1-SNAPSHOT]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[na:1.8.0_291]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[na:1.8.0_291]
at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_291]
org.flowable.common.engine.api.FlowableOptimisticLockingException: Execution[ id ‘d5cff2a4-3c83-11ec-9040-c03eba3cd8b2’ ] - activity ‘sid-D4BCF135-67F9-4F21-8940-DD10FE6D2F03’ - parent ‘d5cff29c-3c83-11ec-9040-c03eba3cd8b2’ was updated by another transaction concurrently
at org.flowable.common.engine.impl.db.DbSqlSession.flushUpdates(DbSqlSession.java:577) ~[flowable-engine-common-6.6.1-SNAPSHOT.jar:6.6.1-SNAPSHOT]
at org.flowable.common.engine.impl.db.DbSqlSession.flush(DbSqlSession.java:364) ~[flowable-engine-common-6.6.1-SNAPSHOT.jar:6.6.1-SNAPSHOT]
at org.flowable.common.engine.impl.interceptor.CommandContext.flushSessions(CommandContext.java:211) ~[flowable-engine-common-6.6.1-SNAPSHOT.jar:6.6.1-SNAPSHOT]
at org.flowable.common.engine.impl.interceptor.CommandContext.close(CommandContext.java:69) ~[flowable-engine-common-6.6.1-SNAPSHOT.jar:6.6.1-SNAPSHOT]
at org.flowable.common.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:92) ~[flowable-engine-common-6.6.1-SNAPSHOT.jar:6.6.1-SNAPSHOT]
at org.flowable.common.spring.SpringTransactionInterceptor.lambda$execute$0(SpringTransactionInterceptor.java:57) ~[flowable-spring-common-6.6.1-SNAPSHOT.jar:6.6.1-SNAPSHOT]
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140) ~[spring-tx-5.2.12.RELEASE.jar:5.2.12.RELEASE]
at org.flowable.common.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:57) ~[flowable-spring-common-6.6.1-SNAPSHOT.jar:6.6.1-SNAPSHOT]
at org.flowable.common.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:30) ~[flowable-engine-common-6.6.1-SNAPSHOT.jar:6.6.1-SNAPSHOT]
at org.flowable.common.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:56) ~[flowable-engine-common-6.6.1-SNAPSHOT.jar:6.6.1-SNAPSHOT]
at org.flowable.common.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:51) ~[flowable-engine-common-6.6.1-SNAPSHOT.jar:6.6.1-SNAPSHOT]
at org.flowable.job.service.impl.asyncexecutor.ExecuteAsyncRunnable.executeJob(ExecuteAsyncRunnable.java:127) [flowable-job-service-6.6.1-SNAPSHOT.jar:6.6.1-SNAPSHOT]
at org.flowable.job.service.impl.asyncexecutor.ExecuteAsyncRunnable.run(ExecuteAsyncRunnable.java:115) [flowable-job-service-6.6.1-SNAPSHOT.jar:6.6.1-SNAPSHOT]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[na:1.8.0_291]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[na:1.8.0_291]
at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_291]
org.flowable.common.engine.api.FlowableOptimisticLockingException: Execution[ id ‘d5cff2a4-3c83-11ec-9040-c03eba3cd8b2’ ] - activity ‘sid-D4BCF135-67F9-4F21-8940-DD10FE6D2F03’ - parent ‘d5cff29c-3c83-11ec-9040-c03eba3cd8b2’ was updated by another transaction concurrently
at org.flowable.common.engine.impl.db.DbSqlSession.flushUpdates(DbSqlSession.java:577) ~[flowable-engine-common-6.6.1-SNAPSHOT.jar:6.6.1-SNAPSHOT]
at org.flowable.common.engine.impl.db.DbSqlSession.flush(DbSqlSession.java:364) ~[flowable-engine-common-6.6.1-SNAPSHOT.jar:6.6.1-SNAPSHOT]
at org.flowable.common.engine.impl.interceptor.CommandContext.flushSessions(CommandContext.java:211) ~[flowable-engine-common-6.6.1-SNAPSHOT.jar:6.6.1-SNAPSHOT]
at org.flowable.common.engine.impl.interceptor.CommandContext.close(CommandContext.java:69) ~[flowable-engine-common-6.6.1-SNAPSHOT.jar:6.6.1-SNAPSHOT]
at org.flowable.common.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:92) ~[flowable-engine-common-6.6.1-SNAPSHOT.jar:6.6.1-SNAPSHOT]
at org.flowable.common.spring.SpringTransactionInterceptor.lambda$execute$0(SpringTransactionInterceptor.java:57) ~[flowable-spring-common-6.6.1-SNAPSHOT.jar:6.6.1-SNAPSHOT]
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140) ~[spring-tx-5.2.12.RELEASE.jar:5.2.12.RELEASE]
at org.flowable.common.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:57) ~[flowable-spring-common-6.6.1-SNAPSHOT.jar:6.6.1-SNAPSHOT]
at org.flowable.common.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:30) ~[flowable-engine-common-6.6.1-SNAPSHOT.jar:6.6.1-SNAPSHOT]
at org.flowable.common.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:56) ~[flowable-engine-common-6.6.1-SNAPSHOT.jar:6.6.1-SNAPSHOT]
at org.flowable.common.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:51) ~[flowable-engine-common-6.6.1-SNAPSHOT.jar:6.6.1-SNAPSHOT]
at org.flowable.job.service.impl.asyncexecutor.ExecuteAsyncRunnable.executeJob(ExecuteAsyncRunnable.java:127) [flowable-job-service-6.6.1-SNAPSHOT.jar:6.6.1-SNAPSHOT]
at org.flowable.job.service.impl.asyncexecutor.ExecuteAsyncRunnable.run(ExecuteAsyncRunnable.java:115) [flowable-job-service-6.6.1-SNAPSHOT.jar:6.6.1-SNAPSHOT]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[na:1.8.0_291]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[na:1.8.0_291]
at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_291]
What (I think) - is happening is that both timers fired at the same time. One boundary event ‘won’ and progressed, but the other one rolled back to the original state. At that point one of the timers should still be there and eventually trigger and finish the process. But you’re saying that the timer never fires again?
What’s the duedate of the timers after the optimistic locking exception happened?
What I say is what is inside the log (and in the workflow diagram): the interruptive timer and one shot timer are never fired again, when the non-interruptive one continues ad vitam aeternam.
It means that the workflow never finishes.
It seems that all timers are executed as expected (once for interruptive and one shot, and repeat until end of User Task for the recurrent one), even in case of exception…
Thanks again
BTW I didn’t find a way to attach the corresponding BPMN to this issue
That would be useful, cause I’m not yet following the ‘all timers are executed as expected’. In the case of an optimistic exception, it should be retried, no?
I retried and did some snapshots from DB.
In fact, the main (interruptive) Timer job ended in DeadLetter, by relaunching it I was able to finish the process.
But not really good as behaviour…