flowable / flowable-engine

A compact and highly efficient workflow and Business Process Management (BPM) platform for developers, system admins and business users.
https://www.flowable.org
Apache License 2.0
7.86k stars 2.6k forks source link

In a transaction where multiple parallel tasks are completed, and when the number of required approvals is specified, the information in act_hi_actinst and act_ru_actinst is not correctly deleted #3967

Open 985177520 opened 1 week ago

985177520 commented 1 week ago

ParallelMultiInstanceBehavior image ExecutionEntityManagerImpl image The first step has the attribute set to false. The removal in the second step depends on the isActive attribute of the first step. My understanding is that you are using this attribute for your MULTI_INSTANCE_ACTIVITY_COMPLETED_WITH_CONDITION message, which is causing an error in updating the subsequent node information.

"This is the data in the node table." image

filiphr commented 1 week ago

@985177520 can you please provide an example process showing this problem?

985177520 commented 1 week ago

@985177520 can you please provide an example process showing this problem?

xml: test.bpmn20.json

I have actually implemented your post-processing function, and in the post-processing, I completed the task of '二级审批' The reason I did this is because we have specific business logic. my test

public static void main(String[] args) {

    ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration()
            .setJdbcUrl("jdbc:h2:mem:flowable;DB_CLOSE_DELAY=-1")
            .setJdbcUsername("sa")
            .setJdbcPassword("")
            .setJdbcDriver("org.h2.Driver")
            .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);

    ProcessEngine processEngine = cfg.buildProcessEngine();
    RepositoryService repositoryService = processEngine.getRepositoryService();
    Deployment deployment = repositoryService.createDeployment()
            .addClasspathResource("test.bpmn20.xml")
            .deploy();
    ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
            .deploymentId(deployment.getId())
            .singleResult();
    Map<String, Object> values = CustomJsonUtils.parseObject(" {\n" +
            "\t\"_id\": \"86924ea3a93aac23be58770e3728482057\",\n" +
            "\t\"skip\": false,\n" +
            "\t\"initiator\": \"abc\",\n" +
            "\t\"create_time\": 1727430838583,\n" +
            "\t\"reviewers_1\": [\n" +
            "\t\t\"abc\",\n" +
            "\t\t\"def\"\n" +
            "\t],\n" +
            "\t\"reviewers_2\": [\n" +
            "\t\t\"abc\",\n" +
            "\t\t\"def\"\n" +
            "\t],\n" +
            "\t\"reviewers_3\": [\n" +
            "\t\t\"abc\",\n" +
            "\t\t\"def\"\n" +
            "\t],\n" +
            "\t\"reviewers_4\": [\n" +
            "\t\t\"abc\",\n" +
            "\t\t\"def\"\n" +
            "\t],\n" +
            "\t\"level_length\": 10,\n" +
            "\t\"min_count_to_pass_1\": 1,\n" +
            "\t\"min_count_to_pass_2\": 1,\n" +
            "\t\"min_count_to_pass_3\": 1,\n" +
            "\t\"min_count_to_pass_4\": 1,\n" +
            "\t\"min_count_to_pass_5\": 1,\n" +
            "\t\"min_count_to_pass_6\": 1,\n" +
            "\t\"min_count_to_pass_7\": 1,\n" +
            "\t\"min_count_to_pass_8\": 1,\n" +
            "\t\"min_count_to_pass_9\": 1,\n" +
            "\t\"min_count_to_pass_10\": 1\n" +
            "}", Map.class);
    // 启动流程
    ProcessInstance processInstance = processEngine.getRuntimeService().createProcessInstanceBuilder()
            .name("test")
            .processDefinitionId(processDefinition.getId())
            .businessKey("test")
            .variables(values)
            .predefineProcessInstanceId("test")
            .start();
    List<Task> startTask = processEngine.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).list();
    startTask.stream().forEach(x -> {
        processEngine.getTaskService().complete(x.getId());
    });
    List<Task> oneNodeTask = processEngine.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).list();
    oneNodeTask.stream().forEach(x -> {
        processEngine.getTaskService().complete(x.getId());
    });

    // These two parts must be in the same MySQL transaction------start
    try (Connection conn = DriverManager.getConnection("jdbc:h2:mem:flowable;DB_CLOSE_DELAY=-1", "sa", "");
         Statement statement = conn.createStatement()) {

        // 启动事务
        conn.setAutoCommit(false);
        List<Task> twoNodeTask = processEngine.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).list();
        processEngine.getTaskService().complete(twoNodeTask.get(0).getId());

        // 提交事务
        conn.commit();

        System.out.println("Transaction committed successfully.");

    } catch (SQLException e) {
        e.printStackTrace();
    }

    // These two parts must be in the same MySQL transaction------end

    // view database
   System.out.println(JSONUtil.toJsonStr(processEngine.getHistoryService().createHistoricActivityInstanceQuery().processInstanceId(processInstance.getId()).list().stream().filter(x -> x.getActivityType().equals("userTask") && x.getActivityName().equals("二级审批")).collect(Collectors.toList()))); ;

}

my taskBehavior: UserTaskActivityBehavior.json

image

("This usertaskBehavior is just a simplified version for your reference to what operations I am performing inside.)

I can reproduce this issue in versions 6.4.2 and 6.7.2. I'm not sure if version 7.0 has the same issue; you can take a look."

985177520 commented 1 week ago

This is the return value. The process has already progressed to the “三级审批” nodel, but the node information for the “二级审批” node has not ended.

[ { "transactionOrder": 4, "activityId": "node_approval_users_2", "activityName": "二级审批", "activityType": "userTask", "executionId": "70", "assignee": "abc", "taskId": "76", "tenantId": "", "processInstanceId": "test", "processDefinitionId": "process_8e540fa243f247d7b337eac6cdc7f471:1:4", "startTime": 1727604239463, "endTime": 1727604243212, "durationInMillis": 3749, "id": "75", "revision": 1, "isInserted": false, "isUpdated": false, "isDeleted": false, "originalPersistentState": { "executionId": "70", "activityId": "node_approval_users_2", "transactionOrder": 4, "durationInMillis": 3749, "activityName": "二级审批", "endTime": 1727604243212, "assignee": "abc", "taskId": "76" } }, { "transactionOrder": 5, "activityId": "node_approval_users_2", "activityName": "二级审批", "activityType": "userTask", "executionId": "71", "assignee": "def", "taskId": "80", "tenantId": "", "processInstanceId": "test", "processDefinitionId": "process_8e540fa243f247d7b337eac6cdc7f471:1:4", "startTime": 1727604242005, "id": "79", "revision": 1, "isInserted": false, "isUpdated": false, "isDeleted": false, "originalPersistentState": { "executionId": "71", "activityId": "node_approval_users_2", "transactionOrder": 5, "activityName": "二级审批", "assignee": "def", "taskId": "80" } } ]