Hi,
So I have been able to write a unit test that reproducing my issue that I am seeing. I didn't modify any of the settings that come packaged in your activiti unit test framework. I believe just running this unit test in your environment should reproduce the same issue.
I have attached a log file of the stacktrace I see from the unit test as well as all the debug info.
<code lang="java">
package org.activiti;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.test.ActivitiRule;
import org.activiti.engine.test.Deployment;
import org.junit.Rule;
import org.junit.Test;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
public class MyUnitTest {
@Rule
public ActivitiRule activitiRule = new ActivitiRule();
@Test
@Deployment(resources = {"org/activiti/test/my-process.bpmn20.xml"})
public void testImmediateReadAfterSaveTask() {
ProcessInstance processInstance =
activitiRule.getRuntimeService().startProcessInstanceByKey("my-process");
assertNotNull(processInstance);
assertEquals("h2", activitiRule.getProcessEngine().getProcessEngineConfiguration().getDatabaseType());
// get the single task
Task task = activitiRule.getTaskService().createTaskQuery()
.processInstanceId(processInstance.getId()).singleResult();
String id = task.getId();
// verify that initially there is no assignee
assertEquals(null, task.getAssignee());
QueryThread q = new QueryThread(id);
// set the assignee to "assignee"
task.setAssignee("assignee");
activitiRule.getTaskService().saveTask(task);
// QUESTION HERE: Shouldn't saveTaks() in the line above be complete by the time I call q.start()? Why is there
// org.activiti.engine.ActivitiOptimisticLockingException: Task[id=7, name=Activiti is awesome!] was updated by another transaction concurrently
q.start();
}
public class QueryThread extends Thread {
protected String taskId;
public QueryThread(String taskId) {
this.taskId = taskId;
}
// Used to replicate REST call that would query the task and then assign it to someone else
// and then save the task again
public void run() {
Task t = activitiRule.getTaskService().createTaskQuery().taskId(taskId).singleResult();
assertEquals("assignee", t.getAssignee());
t.setAssignee("someone-else");
activitiRule.getTaskService().saveTask(t);
}
}
}
</code>
The test DOES NOT fail every time, but if I run it 10 times I can get it to fail at least 1 time. If I connect to an external database(MySQL) I can get it to fail 9/10 times. What is causing the failure to occur if the saveTask() is atomic and the QueryThread is assigning it to someone else after it verifies that it has been modified? Can you help me understand which threads are fighting for modification?
Thanks in advanced.