MetaERP 从“Oracle EBS 单库单事务”切到“多微服务 + 独立 Schema + 事件总线”后,跨服务不可能再靠一个 COMMIT 保证强一致。它的做法是:单服务内用本地 ACID;

发布时间:2026/9/12 9:51:04
MetaERP 从“Oracle EBS 单库单事务”切到“多微服务 + 独立 Schema + 事件总线”后,跨服务不可能再靠一个 COMMIT 保证强一致。它的做法是:单服务内用本地 ACID; MetaERP 从“Oracle EBS 单库单事务”切到“多微服务 独立 Schema 事件总线”后跨服务不可能再靠一个COMMIT保证强一致。它的做法是单服务内用本地 ACID跨服务用事件驱动 本地消息表/事务消息 Saga 补偿 幂等消费 关账对账最终达到“业财可追、账账可对、月结能关”。下面按“原则 → 机制 → 典型链路 → 异常恢复 → 和传统 ERP 的区别”讲。一、总体原则放弃“跨库强一致”追求“业务最终一致”MetaERP 的跨服务一致性模型可以概括成范围一致性模型单微服务内AR / 采购 / 库存 / 会计引擎本地数据库事务强一致同步调用如校验信用、查主数据短时一致失败快速回退异步跨域发票→会计→GL→收款→核销事件驱动 最终一致财务关账口径强校验子账总账、未清项可解释所以它不是“到处用 2PC”而是核心交易短链路同步 资源预占类似 TCC 思路长流程业财链路Saga / 事件驱动财务结果用对账和关账把“最终一致”钉成“可审计一致”二、核心机制 1本地事务 Outbox事件不丢每个服务只写自己的库。业务数据和“待发事件”在同一个本地事务里落库AR 服务本地事务 insert ar_invoice insert ar_open_item insert outbox_event(event_id, aggregate_id, type, payload, status) commit;提交后再由可靠投递组件把outbox_event发到消息总线。好处发票写成功 → 事件一定存在发票回滚 → 事件不会发不会出现“业务成了、事件丢了”这是跨服务一致性的第一道地基。三、核心机制 2消息总线按“聚合键”保序跨服务不是全局保序而是按业务对象保序invoice_id发票生命周期事件customer_account_id回款 / 信用 / 催收事件contract_id收入确认事件po_id采购—收货—发票匹配事件消息系统按这些 key 路由到固定 partitionpartition 内 FIFO。于是INVOICE_CREATED INVOICE_VALIDATED INVOICE_POSTED RECEIPT_APPLIED INVOICE_CLOSED不会被下游处理成“先收款再开发票”。四、核心机制 3消费端幂等重复不可怕消息语义通常是At-Least-Once所以下游必须幂等。会计引擎 / GL / 核销服务一般会建processed_event ( event_id primary key, source_system, journal_batch_id, status )处理前insert ignore into processed_event(event_id, ...)插入失败 已处理过 直接返回成功。结果MQ 重发 3 次 → 只生成 1 笔凭证同一收款事件重放 → 不会重复核销多账簿CAS / IFRS / 管理账都源自同一个event_id五、核心机制 4Saga 补偿而不是跨库回滚以 P2P 为例采购服务创建 PO本地事务 → 事件PO_CREATED 库存服务收货本地事务 → 事件RECEIPT_DONE 发票服务AP 发票匹配本地事务 → 事件INVOICE_MATCHED 会计引擎生成应付凭证本地事务 → 事件AP_JE_CREATED GL应收/应付统驭更新本地事务如果“会计引擎生成凭证”失败不会回滚 PO / 库存 / 发票库而是标记事件未处理重试或发补偿事件或进异常工作台补偿例子发票不匹配 → 发INVOICE_MATCH_ROLLBACK→ 释放 PO 占用收款撤销 → 发RECEIPT_REVERSAL→ 恢复未清项凭证错误 → 红冲事件而不是 DELETE 原凭证这就是 Saga正向有步骤反向有补偿。六、核心机制 5状态机防“乱序/非法跳转”每个聚合对象有状态约束AR 发票 DRAFT → VALIDATED → POSTED → PARTIALLY_RECEIVED → CLOSED下游收到事件时会校验POSTED 事件当前必须是 VALIDATEDRECEIPT_APPLIED发票必须已 POSTEDCLOSED未清金额 0不合法进event_exception不更新余额告警 / 自动重排 / 人工处理所以即使消息迟到、重发、跨区复制延迟也不会把账弄脏。七、核心机制 6子账—会计引擎—总账的“派生一致”MetaERP 继承并云原生化了 EBS 的 SLA GL 模型业务事件 → 子账状态变化AR/AP/INV/PO → 会计引擎生成日记账 → GL 统驭科目汇总关键约束GL 不直接录应收/应付手工凭证GL 余额 子账汇总派生多账簿凭证都挂source_event_id月结前跑AR 未清项总额 发票 - 收款 - 贷项 - 坏账 SLA 日记账笔数 已处理业务事件数 GL 应收统驭 AR 子账汇总 多账簿来源事件一致只要跨服务漏处理 / 重复处理 / 状态跳变关账报表就会红而不是“看起来平”。八、核心机制 7主数据 / 维度一致性靠“共享域 版本化”客户、供应商、科目、利润中心、项目、组织这些跨服务对象不在每个服务里各存一份“真值”由主数据 / 元数据服务发布事件各服务存只读快照 / 缓存视图规则主数据变更带version业务服务处理旧单据时用旧维度新交易用新维度维度映射错 → 会计引擎拒生成凭证这样避免“AR 里客户名变了GL 报表还用老编码”这种跨服务漂移。九、一次完整链路OTC 跨服务一致OM订单确认 → 事件 ORDER_CONFIRMED 信用服务占用额度本地事务 → 事件 CREDIT_RESERVED INV发货 → 事件 GOODS_ISSUED 会计引擎发出商品/递延成本 → 事件 COGS_DEFERRED 税务/开票开票 → 事件 INVOICE_POSTED AR未清项 1000 会计引擎应收/收入/销项税 GL应收统驭 1000 现金/银行适配回款 → 事件 RECEIPT_CREATED AR未分配收款 980 汇兑财务费用 20 核销服务RECEIPT_APPLIED AR未清项 0 GL银行 980应收 -1000汇兑损益 20任一步失败上游不回滚事件重投 / 补偿 / 异常队列月结前必须清零或留痕十、一句话总结MetaERP 跨服务数据一致性不是“一个事务锁全公司”而是本地事务保单域Outbox 保事件不丢分区保业务内有序幂等保重复无害状态机保状态合法Saga 保失败可补偿子账—SLA—GL 保财务可派生月结对账保最终可审计。对比一下维度Oracle EBSMetaERP跨模块单库 PL/SQL 事务微服务 事件一致性强一致单 DB最终一致 关账强校验回滚ROLLBACK补偿事件 / 红冲 / 异常队列消息接口表批处理Outbox MQ 幂等财务核对子账导入 GL子账派生 GL多账簿同源