Flowable 事务与并发控制:保证流程一致性的关键机制
Flowable 事务与并发控制保证流程一致性的关键机制【免费下载链接】flowable-userguideFlowable最新中文文档,ai自动生成BPM体验地址http://flow.je4.cn/#/login项目地址: https://gitcode.com/gh_mirrors/fl/flowable-userguide一、Flowable 事务模型默认的等待状态机制Flowable 是当前最流行的开源工作流引擎之一它天然以事务方式执行 BPMN 流程。当你启动一个流程实例、完成任务或发送信号时Flowable 会沿着流程图的每一条活跃路径做深度优先遍历一直推进到**等待状态Wait State**才停下来。所谓等待状态就是稍后才执行的任务节点比如用户任务、接收消息任务、定时器事件等。到达等待状态后Flowable 会把当前执行状态持久化到数据库等待下一次触发。这一点非常重要一次 API 调用对应一个事务单元这个单元要么全部成功要么全部回滚。上图展示了事务边界的两种切法左侧是默认的同步方式用户任务补充收货地址和服务任务校验地址处于同一事务中一旦校验失败任务完成操作也会回滚用户任务依然留在数据库里右侧则通过异步延续把生成发票拆成了独立的事务。二、异步延续自定义事务边界的核心武器很多业务场景并不希望一损俱损。例如用户任务完成后要生成发票并发给客户如果生成发票失败用户任务的完成结果不应该被回滚。此时就需要**异步延续Async Continuation**来拆事务。只需在 BPMN 节点上添加flowable:asynctrue扩展属性即可serviceTask idservice1 nameGenerate Invoice flowable:classmy.custom.Delegate flowable:asynctrue /配置了异步延续后Flowable 会在后台创建一个Job作业并持久化到数据库由异步执行器Async Executor的线程池取出来执行。flowable:async可以用于task、serviceTask、scriptTask、sendTask、userTask、subProcess、callActivity等几乎所有任务类型。适用场景耗时操作、与外部系统交互、非核心业务逻辑都适合拆成异步事务避免长时间占用数据库连接和调用线程。三、失败重试机制让流程更健壮Flowable 默认配置下一个 Job 执行异常时会自动重试 3 次。但对于真实业务3 次往往不够灵活你可以通过flowable:failedJobRetryTimeCycle自定义重试次数和重试间隔遵循 ISO 8601 时间格式serviceTask idfailingServiceTask flowable:asynctrue flowable:classorg.flowable.engine.test.jobexecutor.RetryFailingDelegate extensionElements flowable:failedJobRetryTimeCycleR5/PT7M/flowable:failedJobRetryTimeCycle /extensionElements /serviceTask上面的配置表示重试 5 次每次间隔 7 分钟。⚠️重要提醒如果服务带有非事务性副作用比如调用外部支付接口重试可能造成副作用重复执行。这类场景必须做好幂等设计。四、独占任务Exclusive Jobs并发安全的默认防线为什么要独占看下面这个经典场景并行网关后跟着三个异步服务任务它们各自生成一个 Job可能被线程池同时取走执行。当三个分支同时到达并行合并网关时每个事务都看不到其他分支的到来于是都认为需要等待其他分支——结果谁也不会继续流程实例永远卡死在合并网关。乐观锁兜底Flowable 用乐观锁解决这个问题多个事务基于同一行数据做决策时都会递增该数据库行的版本号。先提交者获胜其他事务抛出乐观锁异常随后由 Job 执行器自动重试最终顺利通过合并网关。独占任务如何工作从 Flowable 6 开始所有异步延续和定时器事件默认都是独占的Exclusive。独占意味着同一流程实例的独占 Job 绝不会并发执行——执行器会一次性获取同一流程实例的所有独占 Job交给同一个工作线程串行执行。如果确实想并发可以显式关闭serviceTask idservice flowable:expression${myService.performBooking(hotel, dates)} flowable:asynctrue flowable:exclusivefalse /性能误区澄清独占只限制同一流程实例内的 Job 串行不同流程实例的 Job 依然并行执行。反而因为节点亲和性后续 Job 所需的流程数据已在本地缓存通常整体吞吐更优。五、异步执行器V6 时代的作业调度核心从 Flowable 6 开始异步执行器是唯一可用的 Job 执行机制它采用线程池 数据库表分区的架构定时器作业如边界定时事件存放在ACT_RU_TIMER_JOB到期后转为异步作业异步作业flowable:asynctrue写入ACT_RU_JOB表提交后由事务监听器触发执行重试超过上限的死作业进入ACT_RU_DEADLETTER_JOB死信表供管理员人工排查挂起流程相关的作业进入ACT_RU_SUSPENDED_JOB让获取查询保持精简高效。常用配置项通过SpringProcessEngineConfiguration设置配置项默认值说明asyncExecutorCorePoolSize2线程池核心线程数asyncExecutorMaxPoolSize10线程池最大线程数asyncExecutorNumberOfRetries3重试次数上限超限进入死信表asyncExecutorAsyncJobLockTimeInMillis5 分钟作业锁定时间防止多节点重复执行asyncExecutorResetExpiredJobsInterval60 秒清理过期锁定的周期六、BPMN 事务子流程与补偿长事务的正确姿势事务子流程的三种结局BPMN 的**事务子流程Transaction Sub-process**把一组活动圈成一个业务事务有三种结局成功正常流出后续可用补偿事件撤销取消到达取消结束事件触发补偿后从取消边界事件流出风险终止错误事件未被捕获直接终止且不执行补偿。与 ACID 事务的本质区别务必分清BPMN 事务子流程 ≠ 数据库 ACID 事务。ACID 事务短小精悍、支持回滚而 BPMN 事务可能持续数小时甚至数月比如等待用户审批、等待订单履约天然跨越多个 ACID 事务因此失去隔离性和传统回滚能力。解决之道是补偿Compensation为已成功执行的活动配置补偿处理器当事务取消时逆序调用这些补偿处理器撤销业务影响例如取消酒店预订取消航班预订。 更深入的事务子流程、补偿边界事件与补偿处理器实现可参考官方中文文档 ch07b-BPMN-Constructs.adoc异步执行器细节见 ch18-Advanced.adoc。七、实践建议新手避坑清单 ✅优先保持默认异步延续默认独占绝大多数场景直接使用即可不要轻易关闭拆分要克制只有真正需要独立事务边界的环节才用flowable:asynctrue过度拆分反而增加复杂度做好幂等凡是配置了重试的异步任务业务逻辑必须能容忍重复执行监控死信表定期检查ACT_RU_DEADLETTER_JOB及时发现反复失败的任务补偿尽早设计涉及跨系统、长周期的业务流程从建模阶段就要规划补偿处理器关注锁超时长时间运行的流程实例留意定时器锁与作业锁的过期重置配置。总结Flowable 通过事务边界的默认划分保证单元一致性通过异步延续灵活拆分长流程通过独占任务 乐观锁化解并行网关的并发冲突再借助异步执行器完成可靠调度最后用事务子流程 补偿支撑跨系统长事务。理解这五层机制你就能设计出既高性能又高一致性的工作流应用。如果你想动手实践可以参考仓库中的 SQL 建表脚本sql/create和完整用户指南V6.4.2/docs/userguide/src/zh_CN边看边跑很快就能掌握 Flowable 事务与并发控制的精髓【免费下载链接】flowable-userguideFlowable最新中文文档,ai自动生成BPM体验地址http://flow.je4.cn/#/login项目地址: https://gitcode.com/gh_mirrors/fl/flowable-userguide创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考