cancel
Showing results for 
Search instead for 
Did you mean: 

Synchronized Access to ServiceTask

yangyang_qian
Champ in-the-making
Champ in-the-making
If I have a serviceTask that is always kicked off by various different nodes in the workflow (see the "Find Unfinished" task in the attachment) … but I don't want multiple threads to run the service task at exactly the same time (because they wouldn't want to make two copies for the same unfinished thing) … what is a good way to make sure it will behave well? Should I just synchronize the execute() method? Or is there a bpmn construct for this?
5 REPLIES 5

jbarrez
Star Contributor
Star Contributor
There is no BPMN construct for this. Java based synchronized (probably within the execute()) method would be a solution

yangyang_qian
Champ in-the-making
Champ in-the-making
ok thanks, I guess something like the following would work then? (assuming that we can get our hands on a singleton ToyDb object and that the workflow engine only needs to run on one jvm)

<code>
import java.util.List;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.JavaDelegate;

public class ToyMaker implements JavaDelegate {
private static final ToyDb toys = ToyDb.getSingeltonInstance();

@Override
public void execute(DelegateExecution delegExec) throws Exception {
  synchronized(toys) {
   // gets list of unfinished toys from somewhere …
   List<Toy> needFinishing = toys.getUnfinished();
   // … then do more stuff with the toys
   for (Toy toy : needFinishing) {
    toy.applyVarnish();
   }
  }
}
}
</code>

… but this particular solution wouldn't work properly if the activiti engine was deployed across multiple jvms right? (i.e. if we eventually need two engine deployments pointed to one db)

trademak
Star Contributor
Star Contributor
That's correct, this only works within one jvm.

Best regards,

gordonko
Champ in-the-making
Champ in-the-making
I try to use process variable, instead of DB-based mutex, to implement the same thing but it did not work during a concurrency test. The biz logic always sneaks through and executed more than once

//////////////////////////////////
public void execute(DelegateExecution execution) {
  synchronized (execution) {
   Boolean done = (Boolean) execution.getVariable("ConclusionDone");
   if ( done) {
     return;
   }
   execution.setVariable("ConclusionDone", true);
                  }
                  // do biz logic
   }

Does that mean the variable attached to the execution/process committed in an asynchronized approach. Can someone confirm it?

jbarrez
Star Contributor
Star Contributor
Is this for a single JVM?

Even so, it won't work. The execution is an object that is created on the fly, and thus you will have multiple similar objects for the same database row.

You will need a shared object instance to make it work that you share among the invocations.
Getting started

Tags


Find what you came for

We want to make your experience in Hyland Connect as valuable as possible, so we put together some helpful links.