资讯动态

状态机与 BPMN 怎么选?把同一个客户开通流程画两遍

发布时间:2026/9/27 7:56:08 来源:尧图企业网站定制
状态机与 BPMN 怎么选把同一个客户开通流程画两遍《企业级 Workflow 实战从审批流到 AI Agent》第 04 篇 / 共 24 篇本篇成果同一案例的状态迁移表、可运行 Python 状态机、BPMN 2.0 XML 模型与结构校验。阅读边界code/acmeflow-onboarding.bpmn为带图形坐标的教学交换模型isExecutablefalse已解析并检查引用未部署到 BPMN 引擎。项目衔接第 03 篇 API 仍只实现提交和运营审批本篇后段的签署、到账、ERP 与开通用于完整业务建模尚未接入该 API。团队准备扩展 AcmeFlow。运营经理希望看到一张能讲给业务同事的流程图客户提交申请运营审核通过后等合同和款项最后建 ERP 记录并开通服务。后端开发者则问得更具体资料从 v1 改为 v2 后原审批还能用吗签署先到、到账后到时状态如何计算ERP 结果未知时能否允许“开通”按钮有人建议用状态机有人建议画 BPMN。若把两者当成互斥方案讨论很快会跑偏。我们先拿同一个客户申请分别建模再让两个模型共同接受三个反例付款早到、材料改版、缺少 ERP 确认。看完以后读者应能判断自己正在解决“合法状态变化”还是“跨参与者流程推进”以及模型之外还有哪些机制必须补上。这一篇的实验延续第 01 篇内存模型的业务约束代码另写成适合展示迁移的最小状态机它不覆盖第 03 篇 PostgreSQL API也不是已上线的 BPMN 引擎。使用同一个业务案例不意味着三个教学程序已经合并成一个运行时。系列后续会把模型中的能力逐步接到持久化主线。图 1状态图强调哪些业务阶段可以进入、什么条件才能前进签署与付款作为事实不被强迫成固定的先后状态。一、先把业务对象、状态与事实拆开本例的申请有材料版本。运营批准的是某一版材料不是一个永远有效的客户名称。合同签署也对应具体申请和材料版本财务到账则在本教学范围内对应固定套餐与固定金额。只有当前版本审批、当前版本签署和已核对到账全部成立流程才进入READY。这句话是业务规则和我们使用状态机、BPMN、SQL 还是某个工作流产品无关。最小状态集合是SUBMITTED、APPROVED、READY、ACTIVE与REJECTED。SUBMITTED表示等待运营决定APPROVED表示当前材料已经批准但签署或到账还缺READY表示开通前置条件已满足ACTIVE表示本教学模型中 ERP 与权益开通已确认REJECTED表示审核驳回并结束本次申请。状态名称是可读摘要不是全部证据。即使页面显示READY系统仍要能够查到让它就绪的审批、签署与到账依据。这一设计避免了“到账、签署必须按固定顺序完成”的假设。若财务先确认系统保存付款事实仍让申请等待运营与签署。若合同先签系统保存签署事实仍等待财务。两个独立事实在规则检查时汇合。今天增加一个“征信复核已通过”的条件时可以新增相应事实与判断而不必为所有事件到达顺序排列出更多状态名称。第 03 篇数据库此时只有SUBMITTED、APPROVED、REJECTED。它是第一阶段的可运行切片没有签署和到账入口。第 04 篇先给出完整模型等后续文章引入业务事实表和集成入口时才可让持久化应用进入READY。把图上的终点直接写成已经存在的 API 能力会误导读者我们在此明确分开。二、状态机用迁移、Guard 与 Action 说清楚“能不能”状态机最值得写下来的不是一张漂亮箭头图而是每条箭头的条件。APPROVE只能在待办开放、实例为SUBMITTED、请求中的资料版本等于当前材料版本时发生。通过后记录审批版本与决定进入APPROVED如果签署和到账之前已经到齐也可以按规则直接进入READY。REJECT则结束审核路径但如果系统已对外产生不可忽略的 ERP 效果就不能把它当成一个普通字段改为驳回来掩盖后续处置。SIGNED命令表示在本地接受一项已核对的签署事实必须与当前材料版本匹配。PAYMENT_RECEIVED表示接收到并核实付款事实适用本例固定套餐和金额前提。它们可以在开放实例的不同时段到达。每次接受之后状态机重新判断当前版本是否已获批准、同版签署是否存在、付款是否已核对。只有三项都真状态才能成为READY。ERP_CONFIRMED表示远端已确认创建服务记录不是“HTTP 请求已经发出”。只有READY才允许记录这种确认。ACTIVATE的守卫条件进一步要求 ERP 已确认且进入READY所依赖的事实仍有效。业务动作发生后进入ACTIVE再次执行应被拒绝或按明确幂等规则返回既有结果。第 04 篇状态机只在内存中把开通次数加一不能证明真实权益平台没有重复开通。图 2同一个状态字段可以保留但必须有可审查的合法迁移和前置条件。配套code/state_machine.py将这些规则写在Case.apply()。它用material_version、approved_version、signed_versions、payment_received与erp_created保存判断所需的最小事实状态是面向查询的当前阶段。代码里REVISE将资料升级到 v2、清除当前审批有效性并使申请回到SUBMITTED。旧版签署仍在集合里便于理解“历史保留”与“当前有效”不是同一件事。我们故意不让REVISE在 ERP 已确认后继续执行。此时远端可能已经存在服务记录简单重置本地状态可能造成申请与 ERP 脱节。真正的变更单、撤销或补偿要在后续章节设计。教学代码即使只有几十行也应在危险边界拒绝不理解的操作而不是为了演示顺畅把所有命令都放过去。这段状态机代码仍有清楚的上限。它没有数据库事务、没有鉴权、没有多进程并发所谓“状态变化”只存在于当前 Python 对象。使用它来评审业务迁移是合适的把它部署在 Web 进程中管理真实客户则不合适。第 03 篇 PostgreSQL 代码解决了最小审批记录持久化第 05 篇要进一步处理并发决定与材料版本竞态。三、BPMN用任务、网关和事件说清楚“谁在等谁”BPMN 2.0 由 OMG 维护其 XML 模型可以承载任务、网关、事件和图形布局信息。OMG BPMN 2.0.2 规范与机器可读文件给出了标准文件Camunda 的 BPMN primer则用令牌视角解释顺序流。我们不要求读者记住所有元素本篇只使用足以表达客户开通的几种。开始事件代表申请启动。运营审核是一个人工任务令牌到达时流程等待处理人给出决定。排他网关根据审批结果选择“驳回结束”或“继续”通过后进入并行网关分出等待合同签署与等待款项确认的两条路径。两条路径各放一个消息捕获事件收到对应消息才继续。并行汇合网关等待两条路径都到达然后安排 ERP 服务任务、权益开通服务任务和成功结束事件。Camunda 文档对并行网关的分出与汇合行为有示例核心是汇合点等待每条要求的入边到达。Camunda Parallel Gateway这张图主要回答业务协作问题。运营经理能看到审批之后不是直接开通合同和财务是两个独立责任任意一个尚未完成后续服务任务都不能开始。实施人员能指出哪个元素等待外部消息、哪个网关要求两条路径汇合。相比只读READY状态这种结构更容易讨论“等待由谁负责”“超时以后去哪里”“新增一个法务复核是否需要并行”。图 3本图是阅读入口配套 BPMN XML 文件才保存元素 ID、连线、消息引用和图形坐标。真实文件在code/acmeflow-onboarding.bpmn。它使用 BPMN 2.0 的命名空间定义了开始事件、人工任务、排他网关、两项消息捕获事件、并行分支与汇合、两个服务任务和结束事件也带有用于工具显示的 BPMN DI 坐标。与一张在绘图软件里画的流程截图相比XML 至少让元素、连接与消息类型成为可检查的结构。但这份 XML 标记为isExecutablefalse。审批条件中的approved只是教学表达式文件没有指定某个引擎的表达式语言、任务处理器、消息关联变量、权限、超时或外部 API 配置。我们运行的校验脚本只完成 XML 解析、元素与连线引用检查没有声称它已经通过完整 XSD 验证更没有声称它能直接部署到 Camunda、Flowable 或其他引擎。使用具体引擎时还必须按其版本补齐实现细节并运行实例测试。四、并行汇合会等待两个消息不会自动解决早到消息图上“合同签署”和“财务到账”可以任意先后发生但这里有一个非常具体的时间窗口本篇 BPMN 模型在运营审核通过之后才进入并行分支只有这时两条消息捕获事件才进入等待。假设财务早上九点已经确认到账运营九点零八分才批准材料。九点整那条付款消息抵达时流程令牌还在人工审核任务对应的消息捕获事件尚未激活。仅凭图上的并行网关不能推断这条早到消息已被系统缓存并将在稍后自动命中。要覆盖第 01、02 篇中的“到账先于审批”案例入口必须先把已核实的收款事实持久化带申请 ID、来源编号和关联业务键等流程走到需要付款条件时再查询或按明确协议投递已有事实。另一种做法是改造流程模型让外部事实入口在审批前就可接受消息并定义关联与消费语义。具体引擎可能提供消息缓冲、相关键或订阅机制但这些行为不能从本教学 XML 自动推出必须按选用产品和版本实验验证。以 Camunda 8.9 当前文档为一个具体例子它的消息关联依赖消息名与 correlation key订阅会在实例到达消息捕获事件时打开。它还提供按 TTL 缓冲消息的机制TTL 为零且没有匹配订阅时消息会被丢弃。这个产品行为恰好说明“早到是否保留”必须配置和验证不能说“BPMN 图里画了消息事件所以所有早到事实天然安全”。Camunda Messages 文档介绍了订阅、关联与缓冲规则。对于 AcmeFlow保存已核实业务事实仍是重要的领域设计只依赖短暂消息缓冲不能替代财务对账记录。消息的“类型”也不等于“归属”。ContractSigned表示合同签署这一类事件不说明是哪位客户的合同。实际收到消息时应核对申请 ID、合同 ID、资料版本、签署主体和来源可信度付款消息还涉及金额与收款依据。即使两条消息都存在只要其中一条关联错了客户、错了套餐或是重复的旧版结果流程就不应因为并行汇合到齐而执行 ERP。第 14 篇将重点实现事件信封、来源验证、重复与乱序处理。图 4并行汇合表达两条路径的等待关系早于消息捕获节点激活的事实需要另外持久保存并正确关联。第一个可复验反例是只收到签署回执。模型中签署路径的令牌可以前进但付款路径仍停在等待消息事件并行汇合不能放行。第二个反例是付款和签署都有但签署对应 v1申请材料已经 v2。单看 BPMN 两个消息事件已经被触发图像可能像是“条件齐备”但业务规则仍要求版本一致。模型必须携带当前资料版本并在消息入口或汇合后的业务校验处拒绝旧版事实。被拒绝的事实也应有处置记录不能默默消失。为什么不用一个“等待全部完成”的大节点可以这样画但会牺牲协作信息。合同系统与财务来源不同超时责任也不同当申请卡住时运营需要知道到底缺签署还是缺到账。两条路径能把独立责任显露出来。反过来如果实现团队只有一个稳定接口能够返回经核对的“合同与收款条件均满足”并且此接口自己拥有两项事实的规则与审计那么一个等待节点也可能更简洁。模型粒度应跟业务责任一致不是节点越多越专业。五、材料改版两种模型都必须面对的反例现在把 v1 的申请交给运营审核通过后客户提交了 v2 材料。状态机很容易写出approved_version ! material_version并把实例退回SUBMITTED重新开放审核任务旧版签署可以保存在历史里但不能满足 v2。配套脚本就做了这个实验原本已经到READY的内存案例更新材料后旧版审批命令被拒绝申请保持等待新审核。BPMN 图能表达“回到运营审核”或“触发变更子流程”却不会仅因流程图上有一个人工任务就自动知道数据版本如何比较。某个引擎中的流程变量可以保存申请版本消息关联与服务任务也能读取变量但开发者仍要确定在哪个时刻检查版本以及审批期间材料能否被修改。若审批人打开页面时是 v1点击通过前客户已经提交 v2仅在进入审批任务时验证一次版本就不够提交决定时要再检查对象是否仍为 v1。本篇 BPMN XML 没有画材料改版分支这是有意展示模型边界它只覆盖通过、驳回、并行等待和服务任务正常路径。不能因此认为它已完整表达 AcmeFlow 的每条业务规则。真正要部署时可以增加材料变化消息、取消当前审核、重新生成待办或版本化新实例等设计并写出相应的并发和迁移策略。选哪一种不能由图形编辑器替业务方决定。图 5时间线、状态机 Guard 与 BPMN 实施条件必须一致模型可读不等于约束自动生效。还有一个在图上很容易被误画成“完成”的情形ERP 调用超时。超时只说明本地没有及时拿到结果远端可能已经创建服务记录。状态机应保持“结果未知”或进入对账子状态不允许因为没有收到成功响应就盲目重新创建。BPMN 实施也需要明确错误事件、查询活动、重试或人工处理节点。第 10 篇会讨论 Saga、补偿与对账第 13 篇会讨论如何用业务键向远端查询真实结果。本篇模型把 ERP 画成一个服务任务并不提前替这些故障给出答案。六、把两个实验跑起来并看清验证范围在code目录执行以下两个命令均只使用 Python 标准库python-Xutf8 state_machine.py python-Xutf8 validate_bpmn.py状态机实验先让到账事实早于审批和签署确认APPROVED不会过早变成READY随后签署到达申请进入READY。实验尝试在没有 ERP 确认时调用ACTIVATE守卫条件拒绝确认 ERP 结果之后才进入ACTIVE内存开通计数为 1。另一个案例先走到READY随后材料升到 v2脚本确认旧版本审批命令不能推进新材料。输出中的PASS只代表这些断言通过不能当作生产系统开通一次的证明。XML 校验脚本解析acmeflow-onboarding.bpmn检查 11 个流程节点与 11 条顺序流的引用确认有并行分支和汇合两个网关、两项引用已定义消息的捕获事件。它也检查文件标记为不可直接执行。这种结构检查能发现打错 ID、缺少消息定义等低级问题但不能验证某个 BPMN 引擎是否支持当前模型也不能证明被动等待、消息相关性、超时与异常处理符合业务需求。code/actual-output.txt保存了本次两段脚本的实际输出。这一点值得在博客里明确模型检查、模拟运行和真实引擎执行是三个不同层次。我们已经完成前两者的一部分状态机脚本实际运行BPMN XML 实际解析和引用校验。我们没有启动 Camunda也没有执行 XML 中的人工任务和服务任务。若读者把文件导入某个建模器它可以作为讨论起点但部署前仍要补表达式、Worker、消息相关性与错误处理然后以实例级实验重新验收。在一篇教程中展示真正的 XML 而不是只放一张 PNG有一个直接好处读者可以打开文件搜索Gateway_Join、Message_ContractSigned或Flow_Approve看到图上的名称如何变成可检查的引用。后续改动可以做代码审查讨论增加的是一条分支、一种消息还是一项任务而不只是比较两张看上去差不多的图片。审核结果不明时模型应该怎么表现我们在 XML 里为“通过”和“驳回”各写了一条带条件的顺序流没有让“其他所有情况”默认落入驳回。若审批系统返回空结果或新的决定类型直接当作驳回会制造错误的业务终态比较安全的做法是停止推进并暴露一个可处理的异常让实施团队补齐映射或由授权人员裁决。当前模型没有引擎配置因此这只是设计约束尚无引擎执行日志可证明它在某个产品中如何处理未知表达式。同样两条并行路径上的消息可能各来两次。图中的消息捕获事件表达等待一种消息至于重复的PAY-001是否影响流程、第一条与第二条哪条更可信需要入口去重和领域事实校验。不能将“令牌已经经过付款事件”理解成“所有重复付款事件都已经安全处理”。流程模型可以显示消费者在何处等待但消息系统的交付语义、业务编号的唯一约束和最终效果的幂等检查仍要由实施设计明确承担。一次严肃的模型评审可以让业务方逐个指认开始条件、每项人工责任、每个外部事实来源、每条结束路径和每种无法自动处理的异常。开发者再把这些项目映射到 API、数据库表、Worker 或引擎任务。若有一个元素没有负责人图形看起来再完整也会在运行时形成无人处理的申请。反过来若代码里有一个改变客户权益的动作却在模型和验收中找不到对应边界就说明实际系统行为已经超出经过业务讨论的流程。七、如何选择先问要共同讨论什么当团队主要争论“在这个状态下是否允许这个命令”状态迁移表是最短路径。它适合检查终态是否可复活、资料版本是否过期、ERP 结果未确认时能否开通。代码和数据库约束也能直接围绕这些判断实现。对于三步审批、少量条件的流程一张清楚的状态机和持久任务表可能足以支撑业务不需要仅为了使用一个标准而增加流程引擎。当团队主要争论“有哪些角色、谁在等待谁、两项条件能否并行、超时后交给谁”BPMN 的图形表达更有沟通价值。业务方能在模型上指出路径缺失开发者能将元素与实现任务对应。若选用支持这些元素的引擎模型还可能成为执行定义的一部分具体支持范围和扩展语法仍要以引擎版本为准。BPMN 不意味着可以跳过单个业务动作中的版本、权限、幂等和远端确认。图 6状态规则与流程表达可以配合使用。共同底座是业务标识、权限、条件、故障处理和可执行验收。如果团队已经使用 BPMN也可以在一个任务或服务入口内部用状态规则校验对象。若团队使用代码驱动的持久执行也可以把 BPMN 作为需求沟通与流程评审图但必须说明它与运行代码之间如何保持一致。最危险的状态不是“选错工具”而是业务图显示一套流程、实际代码执行另一套、监控再解释第三套。每一次模型变更都应有实例测试对应尤其是流程在运行中升级时。一个可操作的对照办法是对同一份申请同时填写两张工作纸。第一张列“当前阶段、输入命令、守卫条件、状态变化和写入记录”第二张列“令牌所在元素、负责参与者、正在等待的消息、下一条顺序流和超时出口”。当业务方提出“客户在审批后补交材料”第一张纸会逼我们回答旧审批是否失效第二张纸会逼我们回答原人工任务和并行等待要不要取消。两张纸得到的答案应当一致如果互相矛盾先修业务约定再改代码或图。对于长时间运行的实例模型还要回答“新版本规则何时生效”。今天更新状态机中的 Guard不代表昨天已在等待付款的申请应该突然采用新规则今天改 BPMN 图也不代表正在旧模型里运行的令牌会自动跳到新节点。流程定义版本、实例遵循的规则版本以及数据结构迁移是三个需要分别规划的对象。本季第 12 篇会专门用运行中的旧申请做升级实验本篇先让读者在两个模型中都保留版本这个问题。做实施评审时我会要求两种模型给出同一张“失败结果卡”输入是什么、处理前状态是什么、哪个条件拒绝推进、拒绝后申请停在哪里、下一位负责处理的人是谁。例如 ERP 已创建但服务权益开通失败状态机不能只抛出一个异常就让实例永远停在READYBPMN 也不能画一条通向“失败结束”的箭头却没有对账、重试或人工负责人的定义。失败结果卡迫使图和代码共同面对真实运维问题。第 10、16 篇会进一步把它变成补偿策略和故障处置手册。从性能角度看也不要把图上的并行分支误解为“必然启动两个操作系统线程”。BPMN 的并行语义说明两条路径都被激活可以分别等待实际执行由引擎实现和任务配置决定。状态机同样可以同时记录签署与付款两个独立事实而无需为每个事实开一条线程。我们选择并行网关是为了表达两个条件可以独立完成并在汇合点共同检查而不是为了宣称这个模型会自动提高吞吐量。八、验收与 Workflow Thinking读者可以用三组输入复验本文。正常路径中当前版本审批、签署、到账都成立ERP 确认后才允许激活早到路径中付款先到仍不会自动使申请就绪BPMN 实施还需持久化并在等待节点重放或查询该事实改版路径中v1 审批和签署仍能在历史中看到却不能推进 v2。每组实验都要求指出“读到什么记录”“状态为何如此”“图上的令牌停在哪里”而不是只看最后一行PASS。可进一步做一个桌面演练让一位同事扮演运营一位扮演合同系统一位扮演财务。随机打乱签署、到账、审批的顺序并在中途插入材料改版。每次有人提交消息都先写下申请 ID 和材料版本再由规则判断是否接受。若模型无法清楚解释其中任一排列就先修模型和业务约定再考虑部署引擎。桌面演练成本很低却常能在编码前暴露“事实在哪里保存”和“旧任务何时失效”的问题。Workflow Thinking一张 BPMN 图能否作为系统的唯一真相只有在执行逻辑、消息入口、数据版本、权限和图中语义保持一致并能以实例记录验证时它才真正反映运行中的系统。本篇 XML 是一份可交换的教学模型状态机脚本是一份可运行的规则实验二者让我们从不同角度审查同一业务但都需要后续的数据库、事件接入和失败处置来落实。下一篇会先处理最容易发生的并发审批两个人在同一时刻点击不同决定数据库应该怎样给出单一结果。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑