含:MAFL 派生投影与 SRVT/VIPF 无界集合口径、schd EVENT_ID 写代次与 DEAD 代次替换、运营日时区 fail-fast、缺口索引增删(G-MAFL/G-SRVT-VIPF/G-COMPAT-HTTP/G-REQ-OPEN-UNIQUE,移除 G-JOB-HEARTBEAT)、job 心跳/扫描积压/最近失败指标登记、INV-18 验证映射改为实际测试名。
9.5 KiB
运营航班状态设计
本文是航班状态的唯一现行设计规范。它定义权威数据、处理语义、生命周期和对外投递;其他文档只描述管道或产品验收,不重复定义航班状态规则。
1. 目标与边界
系统从共享 MySQL 信箱接收 SIS/AODB 报文,把结果合并到自有 PostgreSQL 中的航班当前态,再通过 outbox 投递 Kafka。共享信箱和 Kafka 都不是状态权威,也不在本地事务的提交范围内。
FLID是航班实例的唯一标识;不得由航班号、日期或资源号推断身份。FLIGHT_SCHD及其明细表是唯一权威当前态;展示视图只读,不能作为写入或对账来源。- 单活动主泵按信箱 FIFO 推进。事务内
PIPELINE_LOCK只串行化本地状态提交,不替代选主或消息认领。 - 状态写入、outbox 事件、处理终态和回填意图在同一 PostgreSQL 事务中提交;回填与 Kafka 投递在提交后独立重试。
现场目标库为 Oracle 11g;当前已验证的实现基准是 PostgreSQL。Oracle 适配未完成前,不能把它视为可切换的运行时选项。
2. 权威模型
| 对象 | 职责 |
|---|---|
FLIGHT_SCHD |
一行一个 FLID,保存标量字段、STATE、STATE_VERSION、OPERATION_DAY、最近消息 ID 和审计时间。 |
| 资源明细表 | 当前 8 张表保存登机门、值机柜台、转盘、计划机位、滑槽、延误、靠撤桥、轮挡等变长集合;SRVT/VIPF 专用明细尚未实现 [G-SRVT-VIPF]。主键为 (FLID, ORDINAL)。 |
FLIGHT_ROUTE_POINT |
ROUT 与 ERUT 两类路线点,使用 ROUTE_KIND 区分;主键应包含该列,避免两类路线的序号冲突。 |
PROC_STATE |
信箱消息的处理终态、业务身份幂等记录,以及回填事实(RECEIVED_AT / BACKFILL_*)。 |
MSG_EVENT |
事务 outbox,承载整态投影、变更通知和删除 tombstone。 |
INBOX_CURSOR |
共享信箱消费水位(读取进度,与处理标记互不替代)。 |
SCHD_SNAP_LOG |
日计划处理留痕,只追加、可重建,不参与状态决策。 |
2.1 航班身份与运营日
FLID 是主键。OPERATION_DAY 从 SCHD 记录的 SODT 按配置的机场时区和切日规则推导;它不是消息接收日或落库日。
一旦已写入非空 OPERATION_DAY,同一 FLID 不得改到另一个运营日。遇到冲突,整包日计划按协议错误拒绝,既有状态保持不变。尚未由日计划收录的航班可以为 NULL;这不表示该航班没有运营日,只表示当前模型无法为它确定归属日。
2.2 字段与集合
标量与异常对象前缀字段存于主表。协议中的 SRVT、VIPF 是无界集合,目标形态必须按集合完整保存到专用明细表示;当前 wire mapper 与持久化尚未实现 [G-SRVT-VIPF]。MAFL 不是 SIS/XML 入站字段,而是由共享航班的 MAID、FLID、FLNO 生成的主航班派生投影;当前尚未实现 [G-MAFL]。
ORDINAL是持久化顺序,从 1 开始;SOURCE_SEQ是上游序号,允许为空或重复。- 相同资源号不代表同一条分配,禁止按资源号去重。
- 每次持久化完整航班状态时,明细表按该
FLID先删后插,以完整合并结果为准。 - ROUT 与 ERUT 是两类独立集合,不能因相同序号覆盖彼此。
- 主/共享关系以主表的
MAID为事实来源:MAID是共享航班指向主航班FLID的引用(非共享航班为NULL);MAFL只在读取和事件投影时从子航班事实派生,不按入站标量解析或保存。
3. 合并与写入语义
领域决策逻辑(如 FlightStateEngine 及各类 Handler 规则)保持纯粹:它根据当前完整态和已解码报文,返回下一完整态与待发事件,不执行数据库或 Kafka I/O。ScheduleProcessor / FlopProcessor / FdelProcessor / AdftProcessor 是事务协调器,负责在统一事务边界内调用决策逻辑并持久化结果。
3.1 SCHD 日计划
SCHD DNLD/RESP 在整包校验通过后,逐条将报文携带的航班写入当前态。日计划只更新或创建其携带的 FLID,不会因其他航班未出现在本次报文中而删除任何记录;SIS 同向(§3.16 注释 1 要求子系统自行保留前一日延误航班)。
日计划在重叠字段上可以覆盖当前动态值;未携带的字段按合并规则保留,显式清空才清除。每个成功写入的航班推进 STATE_VERSION,并在同一事务登记 KAFKA:schd 与 KAFKA:msg 事件。
字段缺失语义与外部规范冲突:SIS 规定最新日计划中未发送的可选字段表示 AODB 已无该数据、子系统应删除本地已有值(SIS_AODB_RMS-V0.1.md §3.16 注释 4;RESP 与 DNLD 同格式,见 §3.17),并要求以 AODB 最新数据覆盖本地(SIS §1.6.2)。这与上面的"未携带字段保留"相反。确认前两条并存,按 Q13 跟踪,不得据本节推定已与上游对齐。
消息重放由 PROC_STATE 的消息 ID 与 identity_key 控制;已成功提交的消息不得再次写入或重复登记事件。整包校验失败或运营日冲突时,整包不落地。
DNLD、RESP 和 ADFT 均已有路由入口。RESP 的请求匹配闭环、出站请求与超时重发仍是待交付项;未注册处理器不能被视为已实现。
3.2 动态运行事件
FLOP 事件只修改它表达的字段或资源集合,其余航班状态保持不变。每个动态子类型的语义都必须有明确 Handler 规则和回归测试,不能只因已被路由就推定其业务语义完整。
动态事件保留既有 OPERATION_DAY,也不基于接收时间重新推导它。未知或已删除航班的具体处理遵从对应 Handler 的幂等规则。
3.3 删除与重建
FDEL 是业务删除入口:仅在 ACTIVE → DELETED 时推进版本、保留明细并与 tombstone 同事务登记;重复 FDEL 或不存在的航班按幂等成功处理。
物理删除仅由独立历史清理在归档成功后执行。日计划报文不是删除依据。若未经 FDEL 而由生命周期清理,清理前需要登记一次 tombstone;已经 FDEL 的记录不重复发出。
ADFT 的字段缺失语义尚待上游确认。在确认前采用保守的 Set-only 规则:出现字段可更新,缺失字段不清空;不得把它当成日计划或动态全量替换。新建 ADFT 若带可解析的 SODT,按同一运营日规则计算 OPERATION_DAY;否则保留为 NULL。
主/共享航班级联:删除共享航班时更新主航班 MAFL 并向主航班通知;删除主航班时级联删除其子共享关联并发出删除通知;主/共享关系必须一次原子变更,不出现主已删、子残留的半状态。共享航班增量通常只更新并通知主航班,不直接发共享通知。这些语义同样约束 FDEL 之外的生命周期清理。主/共享关联的增删按 FLID 做值比较,不使用引用比较。
SIS 规定删除主航班时必须先删子共享航班、再删主航班,顺序不符时 RMS 应向 AODB 回发 EROR(SIS_AODB_RMS-V0.1.md §1.6.1-1.d,事件定义见 SIS §4.8)。本文的原子级联不发该回报,两者取舍见 Q14。
4. 处理事务与失败规则
所有状态处理遵循下列顺序:
- 主泵只处理 FIFO 队头,解码并绑定业务身份。
- 校验消息结构、声明数量、航班标识和运营日;协议错误标记
DEAD,不提交半包。 - 在一个事务中取得
PIPELINE_LOCK,读取当前完整态,计算下一状态,写主表和明细表,登记 outbox 和回填意图。 - 同一事务提交处理终态;任一步失败则整体回滚并按错误类别重试或终止。
- 提交后回填共享信箱并异步投递 outbox;后续失败不得把已提交的
SUCCEEDED改回失败。
identity_key 由 发送方|类型|子类型|序号 构成,用于业务重复检测。STATE_VERSION 是单航班的单调版本,供下游判定新旧;它不是日计划版本,也不表示运营日版本。
5. Kafka 与读取
KAFKA:schd 是按 FLID 的完整状态投影。Dispatcher 可以合并同一 FLID 尚未投递的中间版本,只发最新状态;消费端用 (FLID, STATE_VERSION, UPDATED_AT) 防止旧投影覆盖新状态。
KAFKA:msg 只通知变化,不承载权威状态;两个 topic 不承诺顺序。FDEL 和必要的生命周期清理使用 tombstone:键为 FLID,删除记录以 null 值投递,通知下游移除旧状态。
读取完整航班需要读取主表和全部明细。当前逐航班读取有多次查询,尚未保证跨表一致性快照;批量加载与明确的一致性读边界是后续优化项。
6. 生命周期与开放项
运营日过去不等于航班结束。历史清理须同时满足配置保留期与终态证据或足够静默期,先成功写入历史存储,后物理删除当前态;历史存储失败时必须删除零行。
以下事项仍需确认或交付:
- Oracle 11g 的完整方言与集成验证;
- RESP 请求—应答匹配和出站请求重发;
- ADFT 缺失字段和
FLID重用的上游语义(FLID复用见Q16); - 日计划缺失可选字段的删除语义(与 SIS 的冲突见本文件「合并与写入语义」,
Q13); - 主/共享删除顺序与 EROR 回报义务(Q14);
- 未归属
OPERATION_DAY航班的终止与保留策略; - ROUT/ERUT 联合主键迁移;
- 批量一致性读取,以及动态事件仅在事务内计算一次的收敛。
7. 不变量
航班域不变量的定义处是 invariants.md(INV-11–INV-20),本节不再重复。