use of org.activiti.engine.ActivitiOptimisticLockingException in project Activiti by Activiti.
the class IdentityServiceTest method testUserOptimisticLockingException.
public void testUserOptimisticLockingException() {
User user = identityService.newUser("kermit");
identityService.saveUser(user);
User user1 = identityService.createUserQuery().singleResult();
User user2 = identityService.createUserQuery().singleResult();
user1.setFirstName("name one");
identityService.saveUser(user1);
try {
user2.setFirstName("name two");
identityService.saveUser(user2);
fail("Expected an exception");
} catch (ActivitiOptimisticLockingException e) {
// Expected an exception
}
identityService.deleteUser(user.getId());
}
use of org.activiti.engine.ActivitiOptimisticLockingException in project Activiti by Activiti.
the class AcquireJobsRunnableImpl method run.
public synchronized void run() {
log.info("{} starting to acquire jobs", jobExecutor.getName());
final CommandExecutor commandExecutor = jobExecutor.getCommandExecutor();
while (!isInterrupted) {
isJobAdded = false;
int maxJobsPerAcquisition = jobExecutor.getMaxJobsPerAcquisition();
try {
AcquiredJobs acquiredJobs = commandExecutor.execute(jobExecutor.getAcquireJobsCmd());
for (List<String> jobIds : acquiredJobs.getJobIdBatches()) {
jobExecutor.executeJobs(jobIds);
}
// if all jobs were executed
millisToWait = jobExecutor.getWaitTimeInMillis();
int jobsAcquired = acquiredJobs.getJobIdBatches().size();
if (jobsAcquired >= maxJobsPerAcquisition) {
millisToWait = 0;
}
} catch (ActivitiOptimisticLockingException optimisticLockingException) {
// See https://activiti.atlassian.net/browse/ACT-1390
if (log.isDebugEnabled()) {
log.debug("Optimistic locking exception during job acquisition. If you have multiple job executors running against the same database, " + "this exception means that this thread tried to acquire a job, which already was acquired by another job executor acquisition thread." + "This is expected behavior in a clustered environment. " + "You can ignore this message if you indeed have multiple job executor acquisition threads running against the same database. " + "Exception message: {}", optimisticLockingException.getMessage());
}
} catch (Throwable e) {
log.error("exception during job acquisition: {}", e.getMessage(), e);
millisToWait = jobExecutor.getWaitTimeInMillis();
}
if ((millisToWait > 0) && (!isJobAdded)) {
try {
if (log.isDebugEnabled()) {
log.debug("job acquisition thread sleeping for {} millis", millisToWait);
}
synchronized (MONITOR) {
if (!isInterrupted) {
isWaiting.set(true);
MONITOR.wait(millisToWait);
}
}
if (log.isDebugEnabled()) {
log.debug("job acquisition thread woke up");
}
} catch (InterruptedException e) {
if (log.isDebugEnabled()) {
log.debug("job acquisition wait interrupted");
}
} finally {
isWaiting.set(false);
}
}
}
log.info("{} stopped job acquisition", jobExecutor.getName());
}
use of org.activiti.engine.ActivitiOptimisticLockingException in project Activiti by Activiti.
the class AcquireAsyncJobsDueRunnable method run.
public synchronized void run() {
log.info("starting to acquire async jobs due");
final CommandExecutor commandExecutor = asyncExecutor.getCommandExecutor();
while (!isInterrupted) {
try {
AcquiredJobEntities acquiredJobs = commandExecutor.execute(new AcquireAsyncJobsDueCmd(asyncExecutor));
boolean allJobsSuccessfullyOffered = true;
for (JobEntity job : acquiredJobs.getJobs()) {
boolean jobSuccessFullyOffered = asyncExecutor.executeAsyncJob(job);
if (!jobSuccessFullyOffered) {
allJobsSuccessfullyOffered = false;
}
}
// If all jobs are executed, we check if we got back the amount we expected
// If not, we will wait, as to not query the database needlessly.
// Otherwise, we set the wait time to 0, as to query again immediately.
millisToWait = asyncExecutor.getDefaultAsyncJobAcquireWaitTimeInMillis();
int jobsAcquired = acquiredJobs.size();
if (jobsAcquired >= asyncExecutor.getMaxAsyncJobsDuePerAcquisition()) {
millisToWait = 0;
}
// If the queue was full, we wait too (even if we got enough jobs back), as not overload the queue
if (millisToWait == 0 && !allJobsSuccessfullyOffered) {
millisToWait = asyncExecutor.getDefaultQueueSizeFullWaitTimeInMillis();
}
} catch (ActivitiOptimisticLockingException optimisticLockingException) {
if (log.isDebugEnabled()) {
log.debug("Optimistic locking exception during async job acquisition. If you have multiple async executors running against the same database, " + "this exception means that this thread tried to acquire a due async job, which already was acquired by another async executor acquisition thread." + "This is expected behavior in a clustered environment. " + "You can ignore this message if you indeed have multiple async executor acquisition threads running against the same database. " + "Exception message: {}", optimisticLockingException.getMessage());
}
} catch (Throwable e) {
log.error("exception during async job acquisition: {}", e.getMessage(), e);
millisToWait = asyncExecutor.getDefaultAsyncJobAcquireWaitTimeInMillis();
}
if (millisToWait > 0) {
try {
if (log.isDebugEnabled()) {
log.debug("async job acquisition thread sleeping for {} millis", millisToWait);
}
synchronized (MONITOR) {
if (!isInterrupted) {
isWaiting.set(true);
MONITOR.wait(millisToWait);
}
}
if (log.isDebugEnabled()) {
log.debug("async job acquisition thread woke up");
}
} catch (InterruptedException e) {
if (log.isDebugEnabled()) {
log.debug("async job acquisition wait interrupted");
}
} finally {
isWaiting.set(false);
}
}
}
log.info("stopped async job due acquisition");
}
use of org.activiti.engine.ActivitiOptimisticLockingException in project Activiti by Activiti.
the class ExecutionEntityManager method updateProcessInstanceLockTime.
public void updateProcessInstanceLockTime(String processInstanceId) {
CommandContext commandContext = Context.getCommandContext();
Date expirationTime = commandContext.getProcessEngineConfiguration().getClock().getCurrentTime();
int lockMillis = commandContext.getProcessEngineConfiguration().getAsyncExecutor().getAsyncJobLockTimeInMillis();
GregorianCalendar lockCal = new GregorianCalendar();
lockCal.setTime(expirationTime);
lockCal.add(Calendar.MILLISECOND, lockMillis);
HashMap<String, Object> params = new HashMap<String, Object>();
params.put("id", processInstanceId);
params.put("lockTime", lockCal.getTime());
params.put("expirationTime", expirationTime);
int result = getDbSqlSession().update("updateProcessInstanceLockTime", params);
if (result == 0) {
throw new ActivitiOptimisticLockingException("Could not lock process instance");
}
}
use of org.activiti.engine.ActivitiOptimisticLockingException in project Activiti by Activiti.
the class DuplicateVariableInsertTest method testDuplicateVariableInsertOnTask.
/**
* Test for ACT-1887: Inserting the same new variable at the same time, from 2 different threads, using 2 modified commands that use
* a barrier for starting and a barrier for completing the command, so they each insert a new variable guaranteed.
*/
public void testDuplicateVariableInsertOnTask() throws Exception {
String processDefinitionId = deployOneTaskTestProcess();
final ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinitionId);
final Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
final CyclicBarrier startBarrier = new CyclicBarrier(2);
final CyclicBarrier endBarrier = new CyclicBarrier(2);
final List<Exception> exceptions = new ArrayList<Exception>();
Thread firstInstertThread = new Thread(new Runnable() {
@Override
public void run() {
try {
managementService.executeCommand(new SetTaskVariableWithBarriersCommand(startBarrier, endBarrier, task.getId()));
} catch (Exception e) {
exceptions.add(e);
}
}
});
Thread secondInsertThread = new Thread(new Runnable() {
@Override
public void run() {
try {
managementService.executeCommand(new SetTaskVariableWithBarriersCommand(startBarrier, endBarrier, task.getId()));
} catch (Exception e) {
exceptions.add(e);
}
}
});
firstInstertThread.start();
secondInsertThread.start();
// Wait for threads to complete
firstInstertThread.join();
secondInsertThread.join();
// One of the 2 threads should get an optimistic lock exception
assertEquals(1, exceptions.size());
assertTrue(exceptions.get(0) instanceof ActivitiOptimisticLockingException);
// One variable should be set
Map<String, Object> variables = runtimeService.getVariables(processInstance.getId());
assertEquals(1, variables.size());
assertEquals("12345", variables.get("var"));
runtimeService.deleteProcessInstance(processInstance.getId(), "ShouldNotFail");
}
Aggregations