在这里插入图片描述
服务节点每个都是 异步、并发执行,也就是节点都设置成了flowable:exclusive="false "flowable:async="true"
结果发现 会报错:

2026-03-26 14:37:11.665 DEBUG 27085 --- [         task-2] o.f.common.engine.impl.db.DbSqlSession   : updating: ProcessInstance[26b32078-28de-11f1-9d60-b651931123ce]
2026-03-26 14:37:11.665 DEBUG 27085 --- [         task-2] o.f.e.i.p.e.E.updateExecution            : ==>  Preparing: update ACT_RU_EXECUTION SET REV_ = ? where ID_ = ? and REV_ = ?
2026-03-26 14:37:11.665 DEBUG 27085 --- [         task-2] o.f.e.i.p.e.E.updateExecution            : ==> Parameters: 2(Integer), 26b32078-28de-11f1-9d60-b651931123ce(String), 1(Integer)
2026-03-26 14:37:11.681 DEBUG 27085 --- [         task-2] o.f.e.i.p.e.E.updateExecution            : <==    Updates: 0
2026-03-26 14:37:11.690 DEBUG 27085 --- [         task-7] c.z.v.d.mapper.UserPicMapper.updateById  : <==    Updates: 1
2026-03-26 14:37:11.691 DEBUG 27085 --- [         task-7] c.z.v.d.m.M.selectList                   : ==>  Preparing: SELECT id,process_instance_id,node_id,parent_node_id,execution_id,parent_execution_id,flow_id,flow_deployment_id,make_flow_id,ability_id,seq,create_by,create_date,update_by,update_date,del_flag,remarks FROM make_flow_execution WHERE (node_id = ? AND make_flow_id = ?)
2026-03-26 14:37:11.691 DEBUG 27085 --- [         task-7] c.z.v.d.m.M.selectList                   : ==> Parameters: node_4(String), 74(Long)
2026-03-26 14:37:11.700 DEBUG 27085 --- [         task-2] o.f.c.e.impl.interceptor.LogInterceptor  : --- ExecuteAsyncRunnableJobCmd finished --------------------------------------------------------
2026-03-26 14:37:11.700  INFO 27085 --- [         task-6] com.zuma.video.core.oss.AliOssCloud      : upload##file:images/2037056251241791489.png
2026-03-26 14:37:11.700 DEBUG 27085 --- [         task-2] o.f.c.e.impl.interceptor.LogInterceptor  : --- starting  --------------------------------------------------------
2026-03-26 14:37:11.700 DEBUG 27085 --- [         task-2] o.f.c.s.SpringTransactionInterceptor     : Running command with propagation REQUIRED
2026-03-26 14:37:11.700 DEBUG 27085 --- [         task-7] c.z.v.d.m.M.selectList                   : <==      Total: 1
2026-03-26 14:37:11.702 DEBUG 27085 --- [         task-7] c.z.v.d.m.M.selectList                   : ==>  Preparing: SELECT id,process_instance_id,node_id,parent_node_id,execution_id,parent_execution_id,flow_id,flow_deployment_id,make_flow_id,ability_id,seq,create_by,create_date,update_by,update_date,del_flag,remarks FROM make_flow_execution WHERE (make_flow_id = ? AND seq < ?) ORDER BY seq DESC limit 1
2026-03-26 14:37:11.702 DEBUG 27085 --- [         task-7] c.z.v.d.m.M.selectList                   : ==> Parameters: 74(Long), 100(Integer)
2026-03-26 14:37:11.708 DEBUG 27085 --- [         task-2] o.f.c.engine.impl.agenda.AbstractAgenda  : Operation class org.flowable.engine.impl.interceptor.CommandInvoker$1 added to agenda
2026-03-26 14:37:11.708 DEBUG 27085 --- [         task-2] o.f.e.impl.interceptor.CommandInvoker    : Executing operation class org.flowable.engine.impl.interceptor.CommandInvoker$1
2026-03-26 14:37:11.709 ERROR 27085 --- [         task-2] ltAsyncRunnableExecutionExceptionHandler : Job 26d79786-28de-11f1-9d60-b651931123ce failed

org.flowable.common.engine.api.FlowableOptimisticLockingException: ProcessInstance[26b32078-28de-11f1-9d60-b651931123ce] was updated by another transaction concurrently
	at org.flowable.common.engine.impl.db.DbSqlSession.flushUpdates(DbSqlSession.java:582) ~[flowable-engine-common-6.8.1.jar:6.8.1]
	at org.flowable.common.engine.impl.db.DbSqlSession.flush(DbSqlSession.java:369) ~[flowable-engine-common-6.8.1.jar:6.8.1]
	at org.flowable.common.engine.impl.interceptor.CommandContext.flushSessions(CommandContext.java:212) ~[flowable-engine-common-6.8.1.jar:6.8.1]
	at org.flowable.common.engine.impl.interceptor.CommandContext.close(CommandContext.java:70) ~[flowable-engine-common-6.8.1.jar:6.8.1]
	at org.flowable.common.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:114) ~[flowable-engine-common-6.8.1.jar:6.8.1]
	at org.flowable.common.spring.SpringTransactionInterceptor.lambda$execute$0(SpringTransactionInterceptor.java:57) ~[flowable-spring-common-6.8.1.jar:6.8.1]
	at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140) ~[spring-tx-5.3.31.jar:5.3.31]
	at org.flowable.common.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:57) ~[flowable-spring-common-6.8.1.jar:6.8.1]
	at org.flowable.common.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:35) ~[flowable-engine-common-6.8.1.jar:6.8.1]
	at org.flowable.common.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:56) ~[flowable-engine-common-6.8.1.jar:6.8.1]
	at org.flowable.common.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:51) ~[flowable-engine-common-6.8.1.jar:6.8.1]
	at org.flowable.job.service.impl.asyncexecutor.ExecuteAsyncRunnable.executeJob(ExecuteAsyncRunnable.java:127) [flowable-job-service-6.8.1.jar:6.8.1]
	at org.flowable.job.service.impl.asyncexecutor.ExecuteAsyncRunnable.run(ExecuteAsyncRunnable.java:115) [flowable-job-service-6.8.1.jar:6.8.1]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[na:1.8.0_371]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[na:1.8.0_371]
	at java.lang.Thread.run(Thread.java:750) ~[na:1.8.0_371]


其实发生的原因从日志、源码中可以看出来 ,

protected void flushUpdates() {
        for (Entity updatedObject : updatedObjects) {
            String updateStatement = dbSqlSessionFactory.getUpdateStatement(updatedObject);
            updateStatement = dbSqlSessionFactory.mapStatement(updateStatement);

            if (updateStatement == null) {
                throw new FlowableException("no update statement for " + updatedObject.getClass() + " in the ibatis mapping files");
            }

            LOGGER.debug("updating: {}", updatedObject);

            int updatedRecords = sqlSession.update(updateStatement, updatedObject);
            if (updatedRecords == 0) {
                throw new FlowableOptimisticLockingException(updatedObject + " was updated by another transaction concurrently");
            }

            // See https://activiti.atlassian.net/browse/ACT-1290
            if (updatedObject instanceof HasRevision) {
                ((HasRevision) updatedObject).setRevision(((HasRevision) updatedObject).getRevisionNext());
            }

        }
        updatedObjects.clear();
    }

执行结果,返回更新0条则报错,
update ACT_RU_EXECUTION SET REV_ = ? where ID_ = ? and REV_ = ?
这不就是同时并发,争资源,A、B同时进入,A 更新成功,B 不就是失败了,乐观锁的机制
我设计的流程采用异步并发分支,而并行结束的网关是同步执行的。通过日志分析发现,并行结束的网关存在资源竞争问题。解决方案是为并行结束的网关添加flowable:exclusive=“false” flowable:async="true"属性配置(实现异步执行但独占资源),这样就能有效避免资源竞争问题。同类问题均可采用此方法分析解决。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐