在某些情况下,我们面临接收任务的MismatchingMessageCorrelationException (低于5%)
通知接收任务的回调通过以下方式完成:
protected void respondToCallWorker(
@NonNull final String correlationId,
final CallWorkerResultKeys result,
@Nullable final Map<String, Object> variables
) {
try {
runtimeService.createMessageCorrelation("callWorkerConsumer")
.processInstanceId(correlationId)
.setVariables(variables)
.setVariable("callStatus", result.toString())
.correlateWithResult();
} catch(Exception e) {
e.printStackTrace();
}
}
当我检查日志时:我发现执行的查询是这样的:
select distinct RES.* from ACT_RU_EXECUTION RES inner join ACT_RE_PROCDEF P on RES.PROC_DEF_ID_ = P.ID_ where RES.PROC_INST_ID_ = 'b2362197-3bea-11eb-a150-9e4bf0efd6d0‘and RES.SUSPENSION_STATE_ = '1’and exists (select ID_ from ACT_RU_EVENT_SUBSCR EVT WHERE EVT.EXECUTION_ID_ = RES.ID_ and EVT.EVENT_TYPE_ = 'message‘and EVT.EVENT_NAME_ = 'callWorkerConsumer’)
有时,当我在数据库中查找该进程的实例时,我发现它在接收任务中等待
SELECT DISTINCT * FROM ACT_RU_EXECUTION RES WHERE id_ = 'b2362197-3bea-11eb-a150-9e4bf0efd6d0‘
但是,当我检查订阅事件时,它还没有在数据库中创建
从ACT_RU_EVENT_SUBSCR EVT中选择ID_,其中EVT.EXECUTION_ID_ = 'b2362197-3bea-11eb-a150-9e4bf0efd6d0‘,EVT.EVENT_TYPE_ = 'message’,EVT.EVENT_NAME_ = 'callWorkerConsumer‘
我认为解决方案是在获得respondToCallWorker的响应之前保存“接收任务”,但遗憾的是我不能解决这个问题。
我尝试了“异步之前”callWorker和“消息消费者”,但它不起作用,我也尝试camunda.bpm.database.jdbc-batch-processing=false和得到相同的结果,我也尝试并行分支,但我得到OptimisticLocak异常和MismatchingMessageCorrelationException
也许我做错了
谢谢你的帮忙
发布于 2020-12-14 17:41:01
这是一个有趣的问题。正如您已经发现的,当您尝试在主进程结束其事务之前关联来自"worker“的结果时,就会发生错误,因此在关联时没有注册消息订阅。
这篇blog post对流程编排中的这个问题进行了描述和分析,绝对值得一读。
从这篇文章中可以看出,下面的设计应该可以解决这个问题:
您将消息发送和接收并行化,并在发送任务之前放置异步。这样,发送事件和消息订阅的异步继续作业将写入同一事务中,因此当执行异步消息发送时,订阅已在等待。
虽然这应该可以在BPMN模型级别上解决问题,但考虑不需要重塑流程的选项可能是值得的。首先,你可以发布一个"CallWorkerCommand“(简单的pojo)并在一个spring bean上使用一个TransactionalEventLister来执行实际的调用,而不是直接从你的委托调用worker。通过这样做,您首先将通过订阅消息来完成BPMN流程,然后,spring将执行您的worker调用。其次:您可以在关联消息调用周围使用resilience4j之类的重试机制,因此在极少数情况下,结果很快就会出来,您会失败,并在一秒钟后重试。
我能想到的另一种解决方案是,既然您在这里使用的是“外部worker”模式,那么就是直接使用外部任务服务任务,这样发送/接收同步就可以由Camunda外部worker API解决。
有这么多选择可供选择。我可能更喜欢外部任务,然后是transactionalEventListener,但这是个人喜好的问题。
https://stackoverflow.com/questions/65258112
复制相似问题