cancel
Showing results for 
Search instead for 
Did you mean: 

SQL Deadlock

pault
Star Contributor
Star Contributor
I am hitting a deadlock at a point where 2 threads start processes in quick succession. 9 times out of 10 it is fine, but on occasions I get the deadlock below.

It looks like one thread is starting a process while another is setting variables? I guess I am doing something wrong, any pointers on what that might be based on the error ?

org.apache.ibatis.exceptions.PersistenceException:
### Error updating database.  Cause: org.h2.jdbc.JdbcSQLException: Deadlock detected. The current transaction was rolled back. Details: "
Session #13 (user: SA) is waiting to lock PUBLIC.ACT_HI_ACTINST while locking PUBLIC.ACT_RU_EXECUTION (exclusive), PUBLIC.ACT_HI_PROCINST (exclusive), PUBLIC.ACT_RU_VARIABLE (exclusive), PUBLIC.ACT_GE_BYTEARRAY (exclusive).
Session #9 (user: SA) is waiting to lock PUBLIC.ACT_RU_EXECUTION while locking PUBLIC.ACT_HI_ACTINST (exclusive)."; SQL statement:
insert into ACT_RU_EXECUTION (ID_, REV_, PROC_INST_ID_, BUSINESS_KEY_, PROC_DEF_ID_, ACT_ID_, IS_ACTIVE_, IS_CONCURRENT_, IS_SCOPE_, PARENT_ID_, SUPER_EXEC_)
    values (
      ?,
      1,
      ?,
      ?,
      ?,
      ?,
      ?,
      ?,
      ?,
      ?,
      ?
    ) [40001-132]
### The error may involve org.activiti.persistence.insertExecution-Inline
### The error occurred while setting parameters
### Cause: org.h2.jdbc.JdbcSQLException: Deadlock detected. The current transaction was rolled back. Details: "
Session #13 (user: SA) is waiting to lock PUBLIC.ACT_HI_ACTINST while locking PUBLIC.ACT_RU_EXECUTION (exclusive), PUBLIC.ACT_HI_PROCINST (exclusive), PUBLIC.ACT_RU_VARIABLE (exclusive), PUBLIC.ACT_GE_BYTEARRAY (exclusive).
Session #9 (user: SA) is waiting to lock PUBLIC.ACT_RU_EXECUTION while locking PUBLIC.ACT_HI_ACTINST (exclusive)."; SQL statement:
insert into ACT_RU_EXECUTION (ID_, REV_, PROC_INST_ID_, BUSINESS_KEY_, PROC_DEF_ID_, ACT_ID_, IS_ACTIVE_, IS_CONCURRENT_, IS_SCOPE_, PARENT_ID_, SUPER_EXEC_)
    values (
      ?,
      1,
      ?,
      ?,
      ?,
      ?,
      ?,
      ?,
      ?,
      ?,
      ?
    ) [40001-132]
5 REPLIES 5

pault
Star Contributor
Star Contributor
I read in a reply elsewhere :

Using the activiti API from within activiti-context (JavaDelegate or TaskListeners) is a bad idea, this can mess up command-context and transactions in activiti. When you start a process-instance this way, the thread that drives the execution (which is used to invoke your code) will be used to run the spawned process instance (until it ends or reaches a wait-state).
Could  this is my problem too ? I am starting a process from an object instantiated by a Java Service task. The requirement is to start an exception process in response to some condition, but in a different PVM, so I dont think it can be modelled in the process.

So I think I need to put something like a message queue in between, or somehow force a it onto a new thread in the service task.

In the quote above it says using the API within a JavaDelegate is a bad idea - am I correct in saying that is just those API calls that result in data being committed ?

jbarrez
Star Contributor
Star Contributor
It looks like you are indeed trying to lock the same entity in different threads,
hence the reason why it sometimes works and sometimes not.

Could this is my problem too ? I am starting a process from an object instantiated by a Java Service task. The requirement is to start an exception process in response to some condition, but in a different PVM, so I dont think it can be modelled in the process.

Do you mean starting a process on another Activiti instance?

So I think I need to put something like a message queue in between, or somehow force a it onto a new thread in the service task.

A message queue would be a solution; albeit a heavy one.
It should be possible just to start a new process from a service task.


In the quote above it says using the API within a JavaDelegate is a bad idea - am I correct in saying that is just those API calls that result in data being committed ?

Well, the reason why it is a bad practice, is because the API call will also create a new transaction; new commandcontext, etc.
For a workaround: check how the startProcessInstanceXX actually is run behind the scenes, and call that method.

pault
Star Contributor
Star Contributor
Thanks for the info. I think it gives me enough to work on and understand what is happening. Though having turned off the history service in the process engine that had the issue (it doesn't need it in any case), I haven't seen the problem since.

Do you mean starting a process on another Activiti instance

In the example I am working on I have an application that is implemented as Activiti processes, and which interacts with other Activiti processes (outside my application) that may be running in different process engines. So yes it may be in another process engine instance.

jcosano
Champ in-the-making
Champ in-the-making
Well, the reason why it is a bad practice, is because the API call will also create a new transaction; new commandcontext, etc.

I don't understand this…

If I call to API inside a JavaDelegate class, for sample create a processinstance… then… I'm using the same transaction … is it true??

I think that maybe is useful a small documentation about activiti transactions.

jbarrez
Star Contributor
Star Contributor
Depending on your configuration, it will run in the same transaction. If your are using the default standalone config, all is fine transaction-wise.
 
However, there are a few things going on when you call the API, which might screw it. We advise not to do it, since we havent tested it enought yet to be satisfied.