diff --git a/spring-boot/pom.xml b/spring-boot/pom.xml
index 07d9bf9..114d539 100644
--- a/spring-boot/pom.xml
+++ b/spring-boot/pom.xml
@@ -47,6 +47,11 @@
spring-tx
6.1.3
+
+ org.springframework.retry
+ spring-retry
+ 2.0.8
+
org.springframework.boot
spring-boot-starter-aop
diff --git a/spring-boot/src/main/java/io/vanillabp/camunda8/Camunda8AdapterConfiguration.java b/spring-boot/src/main/java/io/vanillabp/camunda8/Camunda8AdapterConfiguration.java
index 9a698d1..1110752 100644
--- a/spring-boot/src/main/java/io/vanillabp/camunda8/Camunda8AdapterConfiguration.java
+++ b/spring-boot/src/main/java/io/vanillabp/camunda8/Camunda8AdapterConfiguration.java
@@ -38,10 +38,12 @@
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.data.repository.CrudRepository;
+import org.springframework.retry.annotation.EnableRetry;
@AutoConfigurationPackage(basePackageClasses = Camunda8AdapterConfiguration.class)
@AutoConfigureBefore(CamundaAutoConfiguration.class)
@EnableConfigurationProperties(Camunda8VanillaBpProperties.class)
+@EnableRetry
public class Camunda8AdapterConfiguration extends AdapterConfigurationBase> {
private static final Logger logger = LoggerFactory.getLogger(Camunda8AdapterConfiguration.class);
diff --git a/spring-boot/src/main/java/io/vanillabp/camunda8/deployment/Camunda8DeploymentAdapter.java b/spring-boot/src/main/java/io/vanillabp/camunda8/deployment/Camunda8DeploymentAdapter.java
index 1eeec31..560b8ba 100644
--- a/spring-boot/src/main/java/io/vanillabp/camunda8/deployment/Camunda8DeploymentAdapter.java
+++ b/spring-boot/src/main/java/io/vanillabp/camunda8/deployment/Camunda8DeploymentAdapter.java
@@ -21,13 +21,6 @@
import io.vanillabp.camunda8.wiring.Camunda8TaskWiring;
import io.vanillabp.springboot.adapter.ModuleAwareBpmnDeployment;
import io.vanillabp.springboot.adapter.VanillaBpProperties;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.context.event.EventListener;
-import org.springframework.core.io.Resource;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.util.StreamUtils;
-
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Arrays;
@@ -36,8 +29,12 @@
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.event.EventListener;
+import org.springframework.core.io.Resource;
+import org.springframework.util.StreamUtils;
-@Transactional
public class Camunda8DeploymentAdapter extends ModuleAwareBpmnDeployment {
private static final Logger logger = LoggerFactory.getLogger(Camunda8DeploymentAdapter.class);
diff --git a/spring-boot/src/main/java/io/vanillabp/camunda8/deployment/DeploymentService.java b/spring-boot/src/main/java/io/vanillabp/camunda8/deployment/DeploymentService.java
index a8c8934..991ebe4 100644
--- a/spring-boot/src/main/java/io/vanillabp/camunda8/deployment/DeploymentService.java
+++ b/spring-boot/src/main/java/io/vanillabp/camunda8/deployment/DeploymentService.java
@@ -3,10 +3,15 @@
import io.camunda.zeebe.client.api.response.Process;
import io.camunda.zeebe.model.bpmn.Bpmn;
import io.camunda.zeebe.model.bpmn.BpmnModelInstance;
-
import java.io.ByteArrayOutputStream;
import java.time.OffsetDateTime;
import java.util.List;
+import org.springframework.dao.OptimisticLockingFailureException;
+import org.springframework.retry.annotation.Backoff;
+import org.springframework.retry.annotation.Recover;
+import org.springframework.retry.annotation.Retryable;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
public class DeploymentService {
@@ -22,12 +27,17 @@ public DeploymentService(
this.deploymentResourceRepository = deploymentResourceRepository;
}
-
+
+ @Transactional(propagation = Propagation.REQUIRES_NEW)
+ @Retryable(
+ retryFor = OptimisticLockingFailureException.class,
+ maxAttempts = 100,
+ backoff = @Backoff(delay = 100, maxDelay = 500))
public DeployedBpmn addBpmn(
final BpmnModelInstance model,
final int fileId,
final String resourceName) {
-
+
final var previous = deploymentResourceRepository.findById(fileId);
if (previous.isPresent()) {
return (DeployedBpmn) previous.get();
@@ -44,12 +54,31 @@ public DeployedBpmn addBpmn(
return deploymentResourceRepository.save(bpmn);
}
-
+
+ @Recover
+ public DeployedBpmn recoverAddBpmn(
+ final OptimisticLockingFailureException exception,
+ final BpmnModelInstance model,
+ final int fileId,
+ final String resourceName) {
+
+ throw new RuntimeException(
+ "Could not save BPMN '"
+ + resourceName
+ + "' in local DB due to stale OptimisticLockingFailureException", exception);
+
+ }
+
+ @Transactional(propagation = Propagation.REQUIRES_NEW)
+ @Retryable(
+ retryFor = OptimisticLockingFailureException.class,
+ maxAttempts = 100,
+ backoff = @Backoff(delay = 100, maxDelay = 500))
public DeployedProcess addProcess(
final int packageId,
final Process camunda8DeployedProcess,
final DeployedBpmn bpmn) {
-
+
final var versionedId = camunda8DeployedProcess.getProcessDefinitionKey();
final var previous = deploymentRepository.findByDefinitionKey(versionedId);
@@ -71,6 +100,20 @@ public DeployedProcess addProcess(
}
+ @Recover
+ public DeployedProcess recoverAddProcess(
+ final OptimisticLockingFailureException exception,
+ final int packageId,
+ final Process camunda8DeployedProcess,
+ final DeployedBpmn bpmn) {
+
+ throw new RuntimeException(
+ "Could not save Process '"
+ + camunda8DeployedProcess.getBpmnProcessId()
+ + "' in local DB due to stale OptimisticLockingFailureException", exception);
+
+ }
+
public List getBpmnNotOfPackage(final int packageId) {
return deploymentResourceRepository
diff --git a/spring-boot/src/main/java/io/vanillabp/camunda8/service/Camunda8ProcessService.java b/spring-boot/src/main/java/io/vanillabp/camunda8/service/Camunda8ProcessService.java
index c773042..c1829c0 100644
--- a/spring-boot/src/main/java/io/vanillabp/camunda8/service/Camunda8ProcessService.java
+++ b/spring-boot/src/main/java/io/vanillabp/camunda8/service/Camunda8ProcessService.java
@@ -342,7 +342,7 @@ private DE runInTransaction(
Camunda8AdapterConfiguration.ADAPTER_ID,
camunda8Properties.getTenantId(parent.getWorkflowModuleId()),
parent.getWorkflowModuleId(),
- aggregateId == null ? null : aggregateId.toString(),
+ aggregateId.toString(),
bpmnProcessId,
taskIdToTestForAlreadyCompletedOrCancelled,
null,