cancel
Showing results for 
Search instead for 
Did you mean: 

Unique contraint violated - ACT_HI_VARINST(ID_)

badrisudheer
Champ in-the-making
Champ in-the-making
When we have activiti engine running in 2 different servers (trying to setup a clustered environment) pointing to same DB schema. one of the engines is throwing java.sql.SQLIntegrityConstraintViolationException: ORA-00001: unique constraint (APP.SYS_C00386332) violated. This is violating unique constraint is on ACT_HI_VARINST (ID_) column. Here is the constraint definition.
CREATE UNIQUE INDEX "APP"."SYS_C00386332" ON "APP"."ACT_HI_VARINST" ("ID_")

We have come across similar unique constraint issues on ACT_HI_PROCINST(PROC_INST_ID_) column also. Looks like Activiti engine is not using any DB sequence in generating these IDs and some how in this type of clustered environment we are observing the failures on 2 instances trying to save the data to these tables with same ID value.

Please note that we are experiencing this when we tried to perform load testing on a workflow with simple Service Tasks. We were trying to see how Activiti engine handles the requests on high volumes of requests which would initiate multiple process instances for a given process definition in a clustered environment.

Can some one help me understand what may be causing this.

Thanks
Sudheer
5 REPLIES 5

ronald_van_kuij
Champ on-the-rise
Champ on-the-rise
By default Activiti does use a kind of sequence  with batches to get ID blocks, but in a db independent way…  That two servers get the same block sounds kind of strange and I never heard something like this before.

Isn't there by accident old data in the database and the 'sequence' is reset by accident?

frederikherema1
Star Contributor
Star Contributor
There is a property in the ACT_GE_PROPERTY, containing the start of the next "block" of ID's to use, if you're using the default ID-generation strategy. This mechanism will make sure a single engine will use a block of ID's without conflicts, having only one thread allocating a new block. When multiple engines are using the same DB, and they (under heavy load) both fetch a new block at the same time, they will both try to update the 'next.dbid' property in ACT_GE_PROPERTY, one of them should get an ActivitiOptimisticLockException.

If you have duplicate id's, this means this mechanism didn't work as expected, which sounds strange.Can you check if it's a whole block of ID's that are duplicate? Or just a few randomly distributed?

You could also use the StrongUUIDGenerator as id-generator, instead of the DB-approach:


/**
* {@link IdGenerator} implementation based on the current time and the ethernet
* address of the machine it is running on.
*
* @author Daniel Meyer
*/
public class StrongUuidGenerator implements IdGenerator {

badrisudheer
Champ in-the-making
Champ in-the-making
By default Activiti does use a kind of sequence  with batches to get ID blocks, but in a db independent way…  That two servers get the same block sounds kind of strange and I never heard something like this before.

Isn't there by accident old data in the database and the 'sequence' is reset by accident?

We have configured activiti.database.update=true in that environment. So, I hope the old data does stay in ACT_ tables when we do Upgrade of Activiti version and every time we deploy the application. But, I did not understand what do you mean by 'sequence' reset, how can I verify that?

badrisudheer
Champ in-the-making
Champ in-the-making
There is a property in the ACT_GE_PROPERTY, containing the start of the next "block" of ID's to use, if you're using the default ID-generation strategy. This mechanism will make sure a single engine will use a block of ID's without conflicts, having only one thread allocating a new block. When multiple engines are using the same DB, and they (under heavy load) both fetch a new block at the same time, they will both try to update the 'next.dbid' property in ACT_GE_PROPERTY, one of them should get an ActivitiOptimisticLockException.

If you have duplicate id's, this means this mechanism didn't work as expected, which sounds strange.Can you check if it's a whole block of ID's that are duplicate? Or just a few randomly distributed?

You could also use the StrongUUIDGenerator as id-generator, instead of the DB-approach:


/**
* {@link IdGenerator} implementation based on the current time and the ethernet
* address of the machine it is running on.
*
* @author Daniel Meyer
*/
public class StrongUuidGenerator implements IdGenerator {

I did observe ActivitiOptimisticLockException errors in some cases but, in other cases I was seeing Unique constraint violation errors. The big problem is when this happens the workflow for which the exception was thrown gets hung. I do see the 'next.dbid' property in ACT_GE_PROPERTY getting updated. So, It looks like we are using DB-approach. Is StrongUUIDGenerator provided by Activiti framework. If so, How do I set activiti to use StrongUUIDGenerator?

Edit: I did see StrongUuidGenerator under org.activiti.engine.impl.persistence package. Is it thread safe? and how do I set Activiti use StrongUuidGenerator instead of DB-approach?

ronald_van_kuij
Champ on-the-rise
Champ on-the-rise
Is it thread safe?

Search the internet:  http://bit.ly/WAnszH (read the whole topic)

and how do I set Activiti use StrongUuidGenerator instead of DB-approach?
Search the internet: http://bit.ly/116NtOz (hint: read e.g. the ACT-789 at the end)