StaleObjectStateException executing a process with a fork/join in BPMS 6

Solution In Progress - Updated -

Issue

We have a master/sub-process (see the process definitions in the attached kjar) which fail to execute without exception. The master process contains a fork/join, and within the two execution branches, a sub-process is executed. In the sub-process, a timer waits for 15 seconds before the process execution continues. As both timers fire at the same time, two threads reach the join node in parallel, which results in a StaleObjectStateException:

10:29:07,907 INFO  [stdout] (Thread-4 (HornetQ-client-global-threads-219523301)) *** Running After Timer  
10:29:07,910 INFO  [stdout] (Thread-3 (HornetQ-client-global-threads-219523301)) *** Running After Timer  
10:29:07,988 WARN  [com.arjuna.ats.arjuna] (Thread-4 (HornetQ-client-global-threads-219523301)) ARJUNA012125: TwoPhaseCoordinator.beforeCompletion - failed for SynchronizationImple< 0:ffffc0a80014:-3ecffce7:593120fd:2ae, org.hibernate.engine.transaction.synchronization.internal.RegisteredSynchronization@5cba7f8 >: javax.persistence.OptimisticLockException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [org.jbpm.persistence.processinstance.ProcessInstanceInfo#21]
    ...
    at org.drools.core.command.impl.CommandBasedStatefulKnowledgeSession.signalEvent(CommandBasedStatefulKnowledgeSession.java:243) [drools-core-6.5.0.Final-redhat-9.jar:6.5.0.Final-redhat-9]
    at org.jbpm.process.core.async.AsyncSignalEventCommand.execute(AsyncSignalEventCommand.java:46) [jbpm-flow-6.5.0.Final-redhat-9.jar:6.5.0.Final-redhat-9]
    at org.jbpm.executor.impl.AbstractAvailableJobsExecutor.executeGivenJob(AbstractAvailableJobsExecutor.java:122) [jbpm-executor-6.5.0.Final-redhat-9.jar:6.5.0.Final-redhat-9]
    at org.jbpm.executor.impl.jms.JmsAvailableJobsExecutor.onMessage(JmsAvailableJobsExecutor.java:47) [jbpm-executor-6.5.0.Final-redhat-9.jar:6.5.0.F
    at org.kie.server.jms.executor.KieExecutorMDB.onMessage(KieExecutorMDB.java:87) [kie-server-jms-6.5.0.Final-redhat-9.jar:6.5.0.Final-redhat-9]

Note that the execution of the two sub-processes happens in two different threads (Thread-4 and Thread-3). After the exception, the failing transaction is retried due to the retry logic in org.drools.persistence.jpa.OptimisticLockRetryInterceptor, which retries 3 times (not configurable), and the process execution succeeds at the retry:

10:29:08,143 INFO  [stdout] (Thread-4 (HornetQ-client-global-threads-219523301)) *** Running After Timer  
10:29:08,168 INFO  [stdout] (Thread-4 (HornetQ-client-global-threads-219523301)) _____after sub

However, in our real world process, we have seen that the retry attempts could be exhausted, and that the JobExecutor needs to retry the failed job execution. This adds overhead, and if the retry count (configurable with the org.kie.executor.retry.count system property, defaults to 3) in the JobExecutor is exceeded, the process instance is stuck and needs to be resumed manually.

Environment

  • Red Hat JBoss BPM Suite
    • 6.4.0

Subscriber exclusive content

A Red Hat subscription provides unlimited access to our knowledgebase, tools, and much more.

Current Customers and Partners

Log in for full access

Log In

New to Red Hat?

Learn more about Red Hat subscriptions

Using a Red Hat product through a public cloud?

How to access this content