Skip to content

Commit

Permalink
chore(engine): avoid transaction rollback on platform startup
Browse files Browse the repository at this point in the history
- add OptimisticLockingListener to #createHistoryCleanupJob so no
  OptimisticLockingException is thrown in DbEntityManager and then
  caught in CommandContext#close

related to CAM-9671
  • Loading branch information
tmetzke committed Jan 25, 2019
1 parent 9e8cadf commit 5f310f4
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright © 2013-2018 camunda services GmbH and various authors (info@camunda.com)
* Copyright © 2013-2019 camunda services GmbH and various authors (info@camunda.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -17,8 +17,12 @@

import org.camunda.bpm.engine.ProcessEngineBootstrapCommand;
import org.camunda.bpm.engine.impl.context.Context;
import org.camunda.bpm.engine.impl.db.DbEntity;
import org.camunda.bpm.engine.impl.db.EnginePersistenceLogger;
import org.camunda.bpm.engine.impl.db.entitymanager.OptimisticLockingListener;
import org.camunda.bpm.engine.impl.db.entitymanager.operation.DbOperation;
import org.camunda.bpm.engine.impl.interceptor.CommandContext;
import org.camunda.bpm.engine.impl.persistence.entity.EverLivingJobEntity;
import org.camunda.bpm.engine.impl.persistence.entity.PropertyEntity;

/**
Expand All @@ -34,13 +38,26 @@ public Void execute(CommandContext commandContext) {

checkDeploymentLockExists(commandContext);
checkHistoryCleanupLockExists(commandContext);
createHistoryCleanupJob();
createHistoryCleanupJob(commandContext);

return null;
}

protected void createHistoryCleanupJob() {
protected void createHistoryCleanupJob(CommandContext commandContext) {
if (Context.getProcessEngineConfiguration().getManagementService().getTableMetaData("ACT_RU_JOB") != null) {
// CAM-9671: avoid transaction rollback due to the OLE being caught in CommandContext#close
commandContext.getDbEntityManager().registerOptimisticLockingListener(new OptimisticLockingListener() {

@Override
public Class<? extends DbEntity> getEntityType() {
return EverLivingJobEntity.class;
}

@Override
public void failedOperation(DbOperation operation) {
// nothing do to, reconfiguration will be handled later on
}
});
Context.getProcessEngineConfiguration().getHistoryService().cleanUpHistoryAsync();
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright © 2013-2018 camunda services GmbH and various authors (info@camunda.com)
* Copyright © 2013-2019 camunda services GmbH and various authors (info@camunda.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -15,24 +15,25 @@
*/
package org.camunda.bpm.engine.test.concurrency;

import static org.camunda.bpm.engine.ProcessEngineConfiguration.HISTORY_CLEANUP_STRATEGY_END_TIME_BASED;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.camunda.bpm.engine.ProcessEngine;
import org.camunda.bpm.engine.ProcessEngineBootstrapCommand;
import org.camunda.bpm.engine.ProcessEngineConfiguration;
import org.camunda.bpm.engine.ProcessEngines;
import org.camunda.bpm.engine.impl.BootstrapEngineCommand;
import org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.camunda.bpm.engine.impl.context.Context;
import org.camunda.bpm.engine.impl.interceptor.Command;
import org.camunda.bpm.engine.impl.interceptor.CommandContext;
import org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext;
import org.camunda.bpm.engine.impl.persistence.entity.JobEntity;
import org.camunda.bpm.engine.impl.util.ClockUtil;
import org.camunda.bpm.engine.runtime.Job;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

import static org.camunda.bpm.engine.ProcessEngineConfiguration.HISTORY_CLEANUP_STRATEGY_END_TIME_BASED;

/**
* <p>Tests a concurrent attempt of a bootstrapping Process Engine to reconfigure
* the HistoryCleanupJob while the JobExecutor tries to execute it.</p>
Expand Down Expand Up @@ -110,7 +111,8 @@ public void testConcurrentHistoryCleanupJobReconfigurationExecution() throws Int
thread1.reportInterrupts();
thread1.waitForSync();

ThreadControl thread2 = executeControllableCommand(new ControllableProcessEngineBootstrapCommand());
ControllableProcessEngineBootstrapCommand bootstrapCommand = new ControllableProcessEngineBootstrapCommand();
ThreadControl thread2 = executeControllableCommand(bootstrapCommand);
thread2.reportInterrupts();
thread2.waitForSync();

Expand All @@ -128,16 +130,20 @@ public void testConcurrentHistoryCleanupJobReconfigurationExecution() throws Int

assertNull(thread1.getException());
assertNull(thread2.getException());

assertNull(bootstrapCommand.getContextSpy().getThrowable());

assertNotNull(ProcessEngines.getProcessEngines().get(PROCESS_ENGINE_NAME));
}

protected static class ControllableProcessEngineBootstrapCommand extends ControllableCommand<Void> {

protected ControllableBootstrapEngineCommand bootstrapCommand;

@Override
public Void execute(CommandContext commandContext) {

ProcessEngineBootstrapCommand bootstrapCommand = new ControllableBootstrapEngineCommand(this.monitor);
bootstrapCommand = new ControllableBootstrapEngineCommand(this.monitor);

ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration
.createProcessEngineConfigurationFromResource("org/camunda/bpm/engine/test/concurrency/historycleanup.camunda.cfg.xml");
Expand All @@ -150,6 +156,10 @@ public Void execute(CommandContext commandContext) {

return null;
}

public CommandInvocationContext getContextSpy() {
return bootstrapCommand.getSpy();
}
}

protected static class ControllableJobExecutionCommand extends ControllableCommand<Void> {
Expand All @@ -174,19 +184,25 @@ public Void execute(CommandContext commandContext) {
protected static class ControllableBootstrapEngineCommand extends BootstrapEngineCommand implements Command<Void> {

protected final ThreadControl monitor;
protected CommandInvocationContext spy;

public ControllableBootstrapEngineCommand(ThreadControl threadControl) {
this.monitor = threadControl;
}

@Override
protected void createHistoryCleanupJob() {
protected void createHistoryCleanupJob(CommandContext commandContext) {

monitor.sync();

super.createHistoryCleanupJob();
super.createHistoryCleanupJob(commandContext);
spy = Context.getCommandInvocationContext();

monitor.sync();
}

public CommandInvocationContext getSpy() {
return spy;
}
}
}

0 comments on commit 5f310f4

Please sign in to comment.