Clear lock owner and lock exp time from act_ru_job

Hello Flowable colleagues,

I’m looking for a way to manually clear the lock_owner_ and lock_exp_time_ from act_ru_job for a particular lock_owner_. Is this possible with the ProcessEngine or the ManagementService? I did not find a command which clears them. The “ClearProcessInstanceLockTimesCmd” command only clears the process lock_owner and time from act_ru_execution but the jobs are still locked in act_ru_job.

The main issue is that when a flowable engine crashes the lock is not cleared and another async executor will execute the job when the lock_time expires, but in our case, this is 30 minutes. It is not really possible to lower this value because there are jobs that may run for around 30 minutes.

Currently, we have a logic that runs “ClearProcessInstanceLockTimesCmd” when a flowable engine (app instance - it is running on Cloud Foundry) crashes, but this is not enough to unlock the job because this command does not remove the lock_owners from act_ru_job.

Basically, I’m looking for the equivalent of the following query that is implemented by a Command that can be executed from the processEngine, because we want to refrain from using jdbc:
update act_ru_job set lock_owner_ = null, lock_exp_time_ = null where lock_onwer_ = ?;

Looking forward to hearing from you!

Thanks and best regards,
Ivan

Flowable - 6.6.0
DB - Postgresql

Not out of the box, but you could implement your own Command, and then execute it through the ManagementService.

Have a look at e.g. UnlockTimerJobsCmd, but then for a regular job.

1 Like

Hi,
Thank you!
The following implementation worker for me. The jobs get unlocked:

public class ClearJobLockOwnersCmd implements Command<Void> {

    private final List<Job> lockedJobs;
    private final JobServiceConfiguration jobServiceConfiguration;

    public ClearJobLockOwnersCmd(List<Job> lockedJobs, JobServiceConfiguration jobServiceConfiguration) {
        this.lockedJobs = lockedJobs;
        this.jobServiceConfiguration = jobServiceConfiguration;
    }

    @Override
    public Void execute(CommandContext commandContext) {
        JobEntityManager jobEntityManager = jobServiceConfiguration.getJobEntityManager();
        for (Job job : lockedJobs) {
            JobEntity runningLockedJob = jobEntityManager.findById(job.getId());
            if (runningLockedJob != null) {
                runningLockedJob.setLockOwner(null);
                runningLockedJob.setLockExpirationTime(null);
            }
        }
        return null;
    }

}


// Get the JobServiceConfiguration:
processEngine.getProcessEngineConfiguration()
             .getAsyncExecutor()
             .getJobServiceConfiguration();

// Get the Jobs:
processEngine.getManagementService()
             .createJobQuery()
             .lockOwner(lockOwner)
             .list();

// Execute the job:
processEngine.getManagementService()
             .executeCommand(new ClearJobLockOwnersCmd(jobs, jobServiceConfiguration));