数据一致性,用于完成camunda用户任务和更新外部数据库

时间:2019-09-12 12:44:38

标签: rest transactions microservices camunda

我们在应用程序中将camunda用作REST服务。 要在我们的应用中完成用户任务,我们必须执行2个操作:
1.在本地数据库中写入数据
2.通过camunda rest API完成任务

但是此操作不是事务性的。这对我们来说是个问题。

此代码不是事务性代码:

completeUserTask(String taskId, SpecificTaskData userData) {
     dao.update(userData)
     camundaRestApi.completeUserTask(taskId)
}

我看到两个可用的解决方案。两个都将camunda用户任务拆分为2个节点: enter image description here

但是我不喜欢为每个用户任务创建服务任务或消息接收器的想法。
我认为这样会使图表变得不清楚(更加不合理)。
您如何看待这个问题?谢谢。

1 个答案:

答案 0 :(得分:0)

我的建议可能为时已晚:-)

我们还面临着如何将两个操作(写入业务数据和完成任务/发送消息)放在同一个事务中的问题。

我们的解决方案是这样组织方法:

@Transactional
void correlate(String message, String businessKey, DataObject dataObject) {
        dataRepository.update(dataObject);
        runtimeService.correlateMessage(messageCode, businessKey);        
}

当然,您可以使用任何其他触发器来继续流程(完成/提交用户任务)。

另一种方法是创建执行侦听器,它可以从进程上下文中获取数据并将其放入您需要的任何地方(DAO、服务、事件总线等)。此外,通过 Java Config,您可以默认为任何类型的活动添加此类侦听器(无需在 Modeler 中指定):

    public class AddSendEventListenerToBpmnParseListener implements BpmnParseListener {
    
      @Override   public void parseProcess(Element processElement, ProcessDefinitionEntity processDefinition) {
        processDefinition.addBuiltInListener(PvmEvent.EVENTNAME_START, new SendEventListener());
        processDefinition.addBuiltInListener(PvmEvent.EVENTNAME_END, new SendEventListener());   }
    
      @Override   public void parseIntermediateThrowEvent(Element intermediateEventElement, ScopeImpl scope, ActivityImpl activity) {
        activity.addBuiltInListener(PvmEvent.EVENTNAME_START, new SendEventListener());   }
    
      @Override   public void parseStartEvent(Element startEventElement, ScopeImpl scope, ActivityImpl startEventActivity) {   }
    
    // other methods omitted 

}