Java 从消息事件启动的Camunda工作流在出现异常时重复三次

Java 从消息事件启动的Camunda工作流在出现异常时重复三次,java,asynchronous,exception,bpmn,camunda,Java,Asynchronous,Exception,Bpmn,Camunda,背景: 我有三个bpmn图 DMTMain.bpmn DMTSub.bpmn DMTTst.bpmn 以下是他们的服务任务-屏幕截图 1。DMTMain.bpmn 2。DMTSub.bpmn 3。DMTTst.bpmn 第一个DMTMain.bpmn是使用下面代码1中提到的实现调用的 为此,还传递了DMTMain.bpmn的processId 然后在DMTMain.bpmn的MainMsg服务任务中,我们使用startProcessInstanceByMessage()方法调用DMTSub

背景:

我有三个bpmn图

  • DMTMain.bpmn
  • DMTSub.bpmn
  • DMTTst.bpmn
  • 以下是他们的服务任务-屏幕截图

    1。DMTMain.bpmn

    2。DMTSub.bpmn

    3。DMTTst.bpmn

    第一个DMTMain.bpmn是使用下面代码1中提到的实现调用的

    为此,还传递了DMTMain.bpmn的processId

    然后在DMTMain.bpmn的MainMsg服务任务中,我们使用startProcessInstanceByMessage()方法调用DMTSub.bpmn,如下面的代码#2中所述。 (请注意,DMTSub.bpmn是作为MessageEvent启动的)

    所以,在DMTSub.bpmn中启动的进程按照我们的预期行为异步运行。(这就是为什么我们对DMTSub.bpmn使用MessageStartEvent)


    问题:

    在我们的情况下,DMTTst.bpmn过程可能会抛出各种错误,包括与Camunda引擎相关的错误

    • 例如:表达式${TstRunX}中使用了未知属性。原因:无法解析标识符“TstRunX”
    这是预期行为,因为我们正在处理调用方框架(例如:包括DMTMain和DMTSub等)

    所以问题是,, 当DMTTst.bpmn抛出这些类似的错误时,尽管它们在子测试中被捕获,只有DMTSub.bpmn中的SubOut1服务任务在子测试之后执行,并且它返回到错误#1中提到的DMTSub.bpmn打印错误的开始(SubParse),而不执行SubOut2和SubOut3

    这会准确地重复三次。这应该是因为,并且可以通过重试进行更改

  • 屁股下
  • 子测验
  • DMTTst.bpmn处出现异常
  • 次级出口1
  • 屁股下
  • 子测验
  • DMTTst.bpmn处出现异常
  • 次级出口1
  • 屁股下
  • 子测验
  • DMTTst.bpmn处出现异常
  • 次级出口1

  • 预期行为:

    如果从DMTTst.bpmn抛出任何错误,它应该能够在subst(或相等位置)捕获,并继续到SubOut2和SubOut3,而不去开始处

    实际上,我知道我们也可以使用CallActivity调用DMTTst.bpmn。但是我们改变了这一点,因为我们想要捕捉异常

  • 屁股下
  • 子测验
  • DMTTst.bpmn处出现异常
  • 次级出口1
  • 次级出口2
  • 次级出口3

  • 代码#1

    ProcessEngine defaultProcessEngine = BpmPlatform.getProcessEngineService().getDefaultProcessEngine();
    RuntimeService runtimeService = defaultProcessEngine.getRuntimeService();
    ProcessInstanceWithVariables processInstanceWithVariables = null;
    
    try {
    
         processInstanceWithVariables = runtimeService
                    .createProcessInstanceByKey(processId)
                    .setVariables(execution.getVariables())
                    .executeWithVariablesInReturn();
    
            VariableMap variableMap = processInstanceWithVariables.getVariables();
    
    
    } catch (Exception e) {
        e.printStackTrace();
    }
    
    代码#2

    public void execute(DelegateExecution execution) throws Exception {
    
        try {
    
            RuntimeService runtimeService = execution.getProcessEngineServices().getRuntimeService();
            runtimeService.startProcessInstanceByMessage("dmtSub", execution.getVariables());
    
        } catch (Exception e) {
            e.printStackTrace();
        }
    
    }
    
    错误#1:

    15:09:15996警告[org.camunda.bpm.engine.jobexecutor]引擎-14006 执行作业f1377b93-91d8-11ea-b41b-0242c2113c7d时出现异常: org.camunda.bpm.engine.ProcessEngineeException:流程引擎 持续性异常在 org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.rethrow(CommandInvocationContext.java:151) 在 org.camunda.bpm.engine.impl.interceptor.CommandContext.close(CommandContext.java:178) 在 org.camunda.bpm.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:116) 在 org.camunda.bpm.engine.impl.interceptor.JtaTransactionInterceptor.execute(JtaTransactionInterceptor.java:61) 在 org.camunda.bpm.engine.impl.interceptor.ProcessApplicationContextInterceptor.execute(ProcessApplicationContextInterceptor.java:70) 在 org.camunda.bpm.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:33) 在 org.camunda.bpm.engine.impl.jobexecutor.ExecuteJobHelper.executeJob(ExecuteJobHelper.java:51) ..
    ..
    原因:java.sql.SQLException:IJ031070:事务 无法继续:状态\u标记为\u回滚在 org.jboss.jca.adapters.jdbc.WrapperDataSource.checkTransactionActive(WrapperDataSource.java:248) 在 org.jboss.jca.adapters.jdbc.WrappedConnection.checkTransactionActive(WrappedConnection.java:1933) 在 org.jboss.jca.adapters.jdbc.WrappedConnection.checkStatus(WrappedConnection.java:1948) 在 org.jboss.jca.adapters.jdbc.WrappedConnection.checkTransaction(WrappedConnection.java:1922) 在 org.jboss.jca.adapters.jdbc.WrappedConnection.prepareStatement(WrappedConnection.java:452)


    编辑:

    注意,即使我们通过CallActivity或MessageEndEvent通过正常服务任务调用DMTSub.bpmn,也会发生这种情况


    我们也尝试过不同的方法,比如用另一个流程引擎启动DMTTst工作流,在DMTSub工作流的错误结束事件中捕获SubST中抛出的异常,但没有成功。现在尝试一下

    中提到的选项,发现了两种接近预期解决方案的方法

    控制重试

    您可以通过将
    failedJobRetryTimeCycle
    属性放入
    standalone.xml
    文件来控制重试,如下所述

    与数据相关的模式

    R0/PT5S
    
    或者,您可以使用作业配置下的重试时间周期在服务任务/启动事件本身中指定


    捕捉错误和延续

    这可以通过两种方式实现

  • 将边界错误事件添加到整个DMTTst工作流中。

  • DMTTst作为CallActivity调用,并将边界错误事件添加到该中,然后让它进入下一个任务

  • 注意:但在这两种情况下,最好将错误代码添加为java.lang.Exception,如下所述。然后它将捕获属于该类的子类的任何异常。例如:Java异常、无法识别的BPMN属性等

    参考文献:

    <property name="failedJobRetryTimeCycle">R0/PT5S</property>