cancel
Showing results for 
Search instead for 
Did you mean: 

ActivitiOptimisticLockingException: ByteArrayEntity

hbpost
Champ in-the-making
Champ in-the-making
We are getting random ActivitiOptimisticLockingException's and are struggling to understand why.  We do have multiple instances of the Activiti engine running against one database, but there aren't any parallel threads going, and the error occurs on a RuntimeServiceImpl.getVariable() call, as below.  We're fairly certain that there isn't any concurrent access for the process instance either.

Caused by: org.activiti.engine.ActivitiOptimisticLockingException: ByteArrayEntity[id=142051, name=var-facts, size=6455] was updated by another transaction concurrently
        at org.activiti.engine.impl.db.DbSqlSession.flushUpdates(DbSqlSession.java:562)
        at org.activiti.engine.impl.db.DbSqlSession.flush(DbSqlSession.java:444)
        at org.activiti.engine.impl.interceptor.CommandContext.flushSessions(CommandContext.java:170)
        at org.activiti.engine.impl.interceptor.CommandContext.close(CommandContext.java:117)
        at org.activiti.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:66)
        at org.activiti.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:31)
        at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:40)
        at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:35)
        at org.activiti.engine.impl.RuntimeServiceImpl.getVariable(RuntimeServiceImpl.java:124)

When I look at the flushUpdates call, it appears that an update is being performed.

Can someone please explain why an update to ByteArrayEntity would be occurring for a getVariable() call?

Thanks,

Herman Post
4 REPLIES 4

hbpost
Champ in-the-making
Champ in-the-making
Also, in this forum post Activiti process variable version and Optimistic Locking Exception it is stated that HashMaps should not be used as process variables. We are in fact doing this as we have large collections of variables and it is very convenient to contain them in HashMaps.  Is this really not permitted?  All of the classes we put in the HashMap have hashCode implemented, and it is not clear to me why this would be a problem.   Could someone please explain?

Thank you!

frederikherema1
Star Contributor
Star Contributor
It's explained a bit in the post you reference. Serializable variables, when fetched from the DB, are added to a special kind of context. Once the command-context closes (eg. when the getVariables() API call is about to return), these serializables are inspected to see if they have changed -> this is done by comparing the serialized state of the object in-mem, with the state in the DB.

When a hashmap is deserialized, a new bucketlist/tree is build. Since it's a hashmap and most object use virtual address as base for the hashcode, the "keys" hashes in the map will differe every time the map is loaded from DB into memory. So the variable is marked as "stale" by activiti and inserted agian. Offcourse, actual keys and values haven't changed but their hash code could have.

Solution is to either override readObject() and writeObject() to have a stable serialise / deserialize of the map OR use JSON.

Hello.

We have same problem with HashSet variable.

Could we use TreeSet instead ?

hbpost
Champ in-the-making
Champ in-the-making
Thanks for your response, now it is clear to me.