-
Bug
-
Resolution: Done
-
Major
-
jBPM 3.2.7, jBPM 3.2.8
-
None
-
None
In org.jbpm.job.executor.LockMonitorThread#unlockOverdueJobs(), the list of overdue jobs to be unlocked is queried the following way:
Date threshold = new Date(System.currentTimeMillis() - maxLockTime - lockBufferTime);
List overdueJobs = jbpmContext.getJobSession().findJobsWithOverdueLockTime(threshold);
But the query is incorrect, as it returns all jobs where the lockTime is bigger than the threshold, which means that the job has been locked shorter than (maxLockTime + lockBufferTime):
<query name="JobSession.findJobsWithOverdueLockTime">
<![CDATA[
select job
from org.jbpm.job.Job as job
where job.lockTime > :threshold
]]>
</query>
As a result, the LockMonitorThread will set the lockTime and lockOwner to null, where the same Job instance is also updated by a JobExecutorThread, which will lead to a StaleObjectStateException:
ERROR [org.hibernate.event.def.AbstractFlushingEventListener] (JbpmJobExector:LockMonitorThread@169.1.1.1)
Could not synchronize database state with session
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction
(or unsaved-value mapping was incorrect): org.jbpm.job.ExecuteActionJob#123
The 'where' clause in the query needs to be reversed:
Index: modules/core/src/main/resources/org/jbpm/db/hibernate.queries.hbm.xml
===================================================================
— modules/core/src/main/resources/org/jbpm/db/hibernate.queries.hbm.xml (revision 5825)
+++ modules/core/src/main/resources/org/jbpm/db/hibernate.queries.hbm.xml (working copy)
@@ -385,7 +385,7 @@
<![CDATA[
select job
from org.jbpm.job.Job as job
- where job.lockTime > :threshold
+ where job.lockTime < :threshold
]]>
</query>