유동성 프로세스 엔진 문제와 함정

  1. 프로세스 파일 이름의 접두사는 프로세스 정의 자체 프로세스 ID와 일치해야합니다. 프로세스 ID가 "준수 예금 프로세스"의 경우 예를 들면, 프로세스 파일 이름이 프로세스가 전개되었는지 여부를 확인하려면 "준수 예금 프로세스 xxx.bpmn.xml"해야합니다. 사용 processDefinitionQuery 객체

    repositoryService.createProcessDefinitionQuery().list()
  2. 병렬 서브 processses를 시작하려면 "multiInstanceLoopCharacteristics"를 사용

    <callActivity id="callnamescreeningprocess" name="call namescreening process" calledElement="namescreening-process"
    flowable:inheritVariables="true">
    <multiInstanceLoopCharacteristics isSequential="false" flowable:collection="${namesToScreen.result.namesToScreen}" flowable:elementVariable="nameVariableToScreen" >
    <!-- completionCondition></completionCondition -->
    </multiInstanceLoopCharacteristics>
    </callActivity>
  3. 병렬 통화 활동 작업이 조인 될 때 ​​예외 스택 트레이스 로그에 나타납니다. 그러나,이 오류가 계속에서 프로세스에는 영향을주지 않습니다.

    Job 327 failed
    org.flowable.common.engine.api.FlowableOptimisticLockingException: VariableInstanceEntity[id=53, name=nrOfCompletedInstances, type=integer, longValue=1, textValue=1] was updated by another transaction concurrently
    at org.flowable.common.engine.impl.db.DbSqlSession.flushUpdates(DbSqlSession.java:505) ~[flowable-engine-common-6.4.1.jar:6.4.1]
    at org.flowable.common.engine.impl.db.DbSqlSession.flush(DbSqlSession.java:292) ~[flowable-engine-common-6.4.1.jar:6.4.1]
    at org.flowable.common.engine.impl.interceptor.CommandContext.flushSessions(CommandContext.java:191) ~[flowable-engine-common-6.4.1.jar:6.4.1]
    at org.flowable.common.engine.impl.interceptor.CommandContext.close(CommandContext.java:61) ~[flowable-engine-common-6.4.1.jar:6.4.1]
    at org.flowable.common.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:80) ~[flowable-engine-common-6.4.1.jar:6.4.1]
    at org.flowable.common.spring.SpringTransactionInterceptor$1.doInTransaction(SpringTransactionInterceptor.java:49) ~[flowable-spring-common-6.4.1.jar:6.4.1]
    at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140) ~[spring-tx-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.flowable.common.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:46) ~[flowable-spring-common-6.4.1.jar:6.4.1]
    at org.flowable.common.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:30) ~[flowable-engine-common-6.4.1.jar:6.4.1]
    at org.flowable.common.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:56) ~[flowable-engine-common-6.4.1.jar:6.4.1]
    at org.flowable.common.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:51) ~[flowable-engine-common-6.4.1.jar:6.4.1]
    at org.flowable.job.service.impl.asyncexecutor.ExecuteAsyncRunnable.executeJob(ExecuteAsyncRunnable.java:128) [flowable-job-service-6.4.1.jar:6.4.1]
    at org.flowable.job.service.impl.asyncexecutor.ExecuteAsyncRunnable.run(ExecuteAsyncRunnable.java:116) [flowable-job-service-6.4.1.jar:6.4.1]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_191]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_191]
    at java.lang.Thread.run(Thread.java:748) [?:1.8.0_191]
  4. 신호 통지 프로세스 인스턴스를 시작하는 스레드는 별개의 쓰레드로 할 필요가있다. 이 문제는 단위 테스트 케이스에서 특히 두드러진입니다. 프로세스가 아직 해당 "intermediateCatchEvent"노드에 도달하지 않은 반면, 그렇지 않으면 신호는 그 이전에 도달한다.

    val processInstanceId = executionService.startProcess("compliance-deposit-process", "100", listOf(ProcessVariable("deposit_service_host", "localhost:1010"),
    ))
    Thread {
    Thread.sleep(5000)
    executionService.continueProcess(
         processInstanceId, "event-wait-rule-index-completed", listOf(
         ProcessVariable("caseAttributes", caseCreationData))
    )
    }.start()
  5. 병렬 게이트웨이 함정 조인
    초기 프로세스 정의 트랜잭션 모니터 이름 스크리닝 개의 병렬 처리 경로와 평행 게이트웨이 시작한다. 트랜잭션 모니터 실행은 두 개의 논리 분기를 독점 게이트웨이를 시작하고, 모든 지점은 가입 병렬 게이트웨이에 연결하는 직접. 그러나, 결합 병렬 게이트웨이는 종료하지 않습니다.
    유동성 프로세스 엔진 문제와 함정
    단지 이들 두 실제로 실행하는 반면, 접합 병렬 게이트웨이 인바운드 연결 3 가지 유의. 이 병렬 게이트웨이 종료 조건 검사 오류가 발생합니다. org.flowable.engine.impl.bpmn.behavior.ParallelGatewayActivityBehavior를 참조하십시오 :
// Fork

// Is needed to set the endTime for all historic activity joins
CommandContextUtil.getActivityInstanceEntityManager().recordActivityEnd((ExecutionEntity) execution, null);

if (nbrOfExecutionsCurrentlyJoined == nbrOfExecutionsToJoin) {

    // Fork
    if (LOGGER.isDebugEnabled()) {
        LOGGER.debug("parallel gateway '{}' ({}) activates: {} of {} joined", execution.getCurrentActivityId(), 
                execution.getId(), nbrOfExecutionsCurrentlyJoined, nbrOfExecutionsToJoin);
    }
    ...
}

해결 방법은, 제 전용 게이트웨이에서 두 개의 논리 분기 합류 병렬 게이트웨이 가입 경량 더미 스크립트 노드를 추가하는 것이다.

유동성 프로세스 엔진 문제와 함정

  1. Async task delay:
    From the log i found that there when the parent process starts multiple subprocesses, only 2 of them are executed at the same time. The engine triggers another batch after around 10 seconds. The key problem is that i inadventently add "flowable:async=true" to callActivity task. This seems to somehow reorder the task to execute and delay the invoation of subprocess for a while.

    <callActivity id="callnamescreeningprocess" name="call namescreening process" calledElement="namescreening-process"
    flowable:inheritVariables="true" flowable:async="true">

    Checking the code: org.flowable.job.service.impl.asyncexecutor.DefaultAsyncJobExecutor and org.flowable.job.service.impl.asyncexecutor.AcquireAsyncJobsDueRunnable: The aync job acquiring thread first checks remaining capacity in job pool (minimum of threadPoolQueue.remainingCapacity and MaxAsyncJobsDuePerAcquisition) and trying to poll a batch of jobs up to that size. If polled job size = remains capacity, this indicates that there are more job waiting to be executed. The job acquiring thread will not wait and immedidate starts another round of polling, otherwise, the thread pause for asyncExecutorDefaultAsyncJobAcquireWaitTime. Adjusting the variable "maxAsyncJobsDuePerAcquisition" (default value: 1) requires caution. Increase the value does increase throughput, but under cluster environment. It might cause more optimistic locking exception and degrade stability. Adjusting the variable "asyncExecutorDefaultAsyncJobAcquireWaitTime" to lower value (default value: 10000ms) also increase throughtput. But it might increase invalid db polling.

  2. Signal to continue subprocess:
    Sometimes, it is neccessary to continue a subprocess by signal from code. To do that, the processInstanceId of the subprocess must be known. Usually we will store parent processInstanceId in database table. But since the subprocesses are not triggered from code but via a multiInstance callActivity task in parent process definition, the processInstanceIds of the subprocesses are not known directly. A workaround to get the subprocess's processInstanceId is via ExecutionQuery.
val query = runtimeService.createExecutionQuery().activityId("event-wait-namescreening-result").variableValueEquals("nameVariableToScreen", "abc") 
val execution = query.list()[0] 
runtimeService.signalEventReceived(signalName, execution.id, variables.associate {
   Pair(it.name, it.value)
})

The "activityId" parameter takes value of an "intermediateCatchEvent" where the subprocesses are waiting for. This gives a list of subprocess executions that are waiting for the event signal. An additional variable to further distinguish which subprocess we want to signal, this should be the business key stored as a subprocess variable.

문제 :
multiInstanceLoopCharacteristics completionCondition 식 : 식 평가 문맥 다중 인스턴스의 실행 변수에만 액세스 (nrOfActiveInstances, nrOfInstances, nrOfCompletedInstances) 및 상위 (주 공정)을 갖는다. 그것은이 우리가 투표 시나리오에 대해 여러 하위 프로세스를 사용하는 경우 우리가 무엇을 할 수 있는지에 심각한 제한을 부과의 callActivity 실행 범위에 변수를 액세스 할 수 없습니다. 일부 해결 방법은 여기에 설명 : https://blog.csdn.net/weixin_40147618/article/details/83548270

추천

출처blog.51cto.com/shadowisper/2446686