Using SOA/BPM 12.1.3 - By default, a human task has the 'Enable Auto Claim' functionality enabled.
When I first saw this, I was encouraged to think that when a user opens a task, they automatically 'Claim' the instance, so that other users can no longer act on it.
I was wrong.
So what does the 'Enable Auto Claim' actually do? In short, it allows a user to action on the task. That is, 'Submit', 'Approve', etc, whatever actions are defined on the task without having to manually click a 'Claim' button.
That's not what I want.
I had a fairly complex human task in a process, that required someone from a group of users to look up information, add details, and actually spend some time on the form before saving and submitting the task. Immediately into UAT, an 'bug' was submitted after two users tried to submit the same task. They did not want others to be able to work tasks that they had started.
To me, this made sense. Now how can this be done?
To give myself some time, I disabled the 'Auto Claim', and taught the testers to use the 'Claim' button as the very first act on the task. This would 'lock' it from other users, and if they decided not to complete the task, they should use the 'Release' button. This was not a suitable solution for the client, as the testers quickly responded with 'keystrokes save lives', their pun to me about minimizing interaction with the form and maximizing efficiency. So lets save them from having to 'Claim' the task.
As anyone who has tried this before, I immediately went down the path of trying to drag the 'Claim()' method onto the task flow (or call from a managed bean on page load).
At first, I was content with how this worked, until I tried to call one of my other actions on the task. I was prompted with an error saying that the task is out of date, and needs to be refreshed. I was also getting errors trying to display the page a second time. This path was not going to work.
Almost defeated, I wanted to try one more option. Lets use the TaskQueryService to claim the task. From within the taskflow, I have the Worklist Context, and Task Id which is enough information to find the task. Once I have the task, I can check if it's currently claimed, and if not, claim it!
Lets take a look at some code to do this
Attached here is the entire java class for import references.
Here's the trick! Invoke this code from the Task Flow Initializer! Now the task will be claimed (or 'acquired') before the user ever sees the page. They can then 'Release' the task still if they choose not to work it, but other users will now see this task as claimed!
There is behavior to be aware of, that I noticed with this solution.
- If two users have the worklist open, and one of them claims a task, the task still 'appears' to be unclaimed to the second user. They would have to 'refresh' their worklist, or alternatively, put an error message on the UI that says the task is currently claimed by another user. This way, the task is still viewable, but not actionable.
- From the worklist (or workspace), enable the 'Acquired By' column on your view. This displays who currently has the task claimed!
Here is my sample project (12.1.3) demonstrating this!
Auto Release Feature
Additionally, from within EM, you can configure tasks to be released at a configured interval.
Right click on soa-infra → SOA Administration → Workflow Properties
Click the 'Task' tab, and expand 'Advanced' options.
From here the 'Task Auto Release Configuration' can be modified based on Priority.