cancel
Showing results for 
Search instead for 
Did you mean: 

org.activiti.engine.ActivitiOptimisticLockingException

mlisiewicz
Champ in-the-making
Champ in-the-making
Given exception is thrown when two executions try to update their state at the same time. Please download attached activiti file and run simple test on it.

Engine revision 5.3, databases checked: mysql, h2


2011-03-25 14:51:20 org.activiti.engine.impl.interceptor.CommandContext close
SEVERE: Error while closing command context
org.activiti.engine.ActivitiOptimisticLockingException: ExecutionEntity[5] was updated by another transaction concurrently
   at org.activiti.engine.impl.db.DbSqlSession.flushUpdates(DbSqlSession.java:407)
   at org.activiti.engine.impl.db.DbSqlSession.flush(DbSqlSession.java:320)
   at org.activiti.engine.impl.interceptor.CommandContext.flushSessions(CommandContext.java:135)
   at org.activiti.engine.impl.interceptor.CommandContext.close(CommandContext.java:91)
   at org.activiti.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:49)
   at org.activiti.spring.SpringTransactionInterceptor$1.doInTransaction(SpringTransactionInterceptor.java:42)
   at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:130)
   at org.activiti.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:40)
   at org.activiti.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:33)
   at org.activiti.engine.impl.jobexecutor.ExecuteJobsRunnable.run(ExecuteJobsRunnable.java:36)
   at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
   at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
   at java.lang.Thread.run(Unknown Source)
Exception in thread "pool-1-thread-1" org.activiti.engine.ActivitiOptimisticLockingException: ExecutionEntity[5] was updated by another transaction concurrently
   at org.activiti.engine.impl.db.DbSqlSession.flushUpdates(DbSqlSession.java:407)
   at org.activiti.engine.impl.db.DbSqlSession.flush(DbSqlSession.java:320)
   at org.activiti.engine.impl.interceptor.CommandContext.flushSessions(CommandContext.java:135)
   at org.activiti.engine.impl.interceptor.CommandContext.close(CommandContext.java:91)
   at org.activiti.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:49)
   at org.activiti.spring.SpringTransactionInterceptor$1.doInTransaction(SpringTransactionInterceptor.java:42)
   at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:130)
   at org.activiti.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:40)
   at org.activiti.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:33)
   at org.activiti.engine.impl.jobexecutor.ExecuteJobsRunnable.run(ExecuteJobsRunnable.java:36)
   at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
   at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
   at java.lang.Thread.run(Unknown Source)
2011-03-25 14:52:12 org.springframework.context.support.AbstractApplicationContext doClose
INFO: Closing org.springframework.context.support.GenericApplicationContext@19efb05: startup date [Fri Mar 25 14:51:13 CET 2011]; root of context hierarchy
4 REPLIES 4

jbarrez
Star Contributor
Star Contributor
That is the expected behavior: in you case, the two tasks are trying to do something at the same time with the same process instance.
The engine can't possibly know how those must be merged in the generic case (in this case, you can just see it), so one transaction 'wins', and the other is rolled back.

So if you want to deal with this, you will need to catch this exception and implement a reload or retry (depending on your use case)

lichtin
Champ in-the-making
Champ in-the-making
I'm trying to understand this situation and am at a loss.
Why and how does the code identify above scenario as an 'optimistic lock exception'?

There are 2 receive tasks and each task has a boundary timer (3 secs) attached.
Both timers fire and then the process ends. There's no variables to merge.

ronald_van_kuij
Champ on-the-rise
Champ on-the-rise
but there is a proccess to end

franz1
Champ in-the-making
Champ in-the-making
That is the expected behavior: …
The engine can't possibly know how those must be merged in the generic case (in this case, you can just see it), so one transaction 'wins', and the other is rolled back.

So if you want to deal with this, you will need to catch this exception and implement a reload or retry (depending on your use case)

How "big" are those transactions (i.e what is covered by one transaction? Execution of a single task, entire execution till it reaches a receive-task/end?) And is there a way to influence the size of such a transaction (even if you are using Spring in an EJB (with user-managed transactions))?

"OptimisticLocking" sounds like first Activiti tries to do something and only then to check if it was allowed to do it. If that's correct and if I have a service-task starting an asynchronous external process followed by a receive-task waiting for the asynch process to continue - this should mean that the external process is already started when Activiti realizes that it would have been better not to do so and rolls back - which in consequence means that the process can't signal that it has terminated.

This behaviour would be a "no-go" and should be corrected ASAP - Ideally there would be a configuration-option that Activiti checks before each step if it is allowed to perform it - even if it comes at the cost of performance-loss.

Best regards


Franz
Getting started

Tags


Find what you came for

We want to make your experience in Hyland Connect as valuable as possible, so we put together some helpful links.