2026-09-09 10:47:03 +08:00
|
|
|
|
# 航班运行数据接入与当前状态管理设计
|
|
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
本模块从共享 MySQL 信箱接收 AODB 报文,在本地库维护航班当前态,再通过 Kafka 发布变化。
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
未标注内容即规范要求。标注“开放项”“已知偏差”“待定”的内容尚未定案或未完成,全部汇总在 §10。
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
2026-09-09 11:43:34 +08:00
|
|
|
|
## 1. 目标与边界
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
1. **当前态唯一**:AODB 是业务事实来源,本地库是本模块唯一查询源。
|
2026-09-09 11:43:34 +08:00
|
|
|
|
2. **严格有序**:单活动主泵按信箱 FIFO 处理消息。
|
2026-09-09 14:54:54 +08:00
|
|
|
|
3. **原子提交**:航班状态、快照账本、处理结果、待发事件在同一事务提交。
|
|
|
|
|
|
4. **可恢复**:提交后的信箱回填与 Kafka 投递可独立重试,不重算业务。
|
|
|
|
|
|
5. **完整保存**:变长资源用明细表,不用固定槽位截断。
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
边界:只同步报文、维护当前态,不推导取消、延误、备降、返航等业务状态;旅客服务状态不在范围内。`PIPELINE_LOCK` 只能串行化数据库事务,不能代替消息认领、实例选主和故障切换。
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
## 2. 数据来源与语义
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
2026-09-09 11:43:34 +08:00
|
|
|
|
| 来源 | 作用 | 处理方式 |
|
|
|
|
|
|
|---|---|---|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
| SCHD `DNLD` / `RESP` | 建立某运营日的基准名单 | 覆盖单个完整运营日时才换代与差删(§5.2);定时下发的 48 小时窗口只做状态覆盖与 upsert |
|
|
|
|
|
|
| SCHD ADFT | 新增或更新单个临时航班 | 增量合并;不换代、不差删、不完成请求 |
|
|
|
|
|
|
| FLOP | 更新单个航班的运行变化 | 增量合并;不修改运营日、不改名册 |
|
|
|
|
|
|
| FDEL | 终止某个航班运行实例 | 按 `FLID` 删除并移出名单(§6.2);不换代 |
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
字段缺失只有两种含义:
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
- 完整快照(`DNLD`/`RESP`):未出现表示 AODB 当前没有该数据,**清除本地旧值**。
|
|
|
|
|
|
- 增量(`FLOP`/`ADFT`):未出现表示本次没改,**保留本地值**。
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
## 3. 数据模型
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
### 3.1 航班运行实例身份
|
|
|
|
|
|
|
|
|
|
|
|
- **`FLID`**:AODB 分配的航班运行实例 ID(`Number(1-12)`,SIS §3.16.2),是主表、明细表、动态事件、删除事件的唯一关联键。
|
|
|
|
|
|
- **`FLNO`**:展示用航班号,可重复,不参与身份判定。
|
|
|
|
|
|
- **`OPERATION_DAY`**:该实例所属运营日,一经确定不可变(§5.3)。
|
|
|
|
|
|
|
|
|
|
|
|
同一航班号在不同运营日执行 = 不同 `FLID`:
|
|
|
|
|
|
|
|
|
|
|
|
| 输入 | 结果 |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| 9/9 快照含 `FLID=121112312, FLNO=CA100` | 建实例 121112312,`OPERATION_DAY=9/9` |
|
|
|
|
|
|
| 9/10 快照含 `FLID=121119845, FLNO=CA100` | 建实例 121119845,`OPERATION_DAY=9/10` |
|
|
|
|
|
|
| 9/9 新快照不含 121112312 | 进入 9/9 的 `O − N` 差删 |
|
|
|
|
|
|
| 9/10 快照仍含 121119845 | 不受 9/9 差删影响 |
|
|
|
|
|
|
| 9/10 快照错误含 121112312 | 协议异常;不得把旧实例改归 9/10 |
|
|
|
|
|
|
|
|
|
|
|
|
身份变更由 AODB 用「旧 `FLID` 的 FDEL + 新 `FLID` 的 ADFT」表达,本模块不得把两者合并为同一实例,也不得通过航班号或日期推断两个 `FLID` 是同一实例。
|
|
|
|
|
|
|
|
|
|
|
|
### 3.2 表职责
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
2026-09-09 11:43:34 +08:00
|
|
|
|
| 表 | 粒度 | 职责 |
|
|
|
|
|
|
|---|---|---|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
| `FLIGHT_SCHD` | 每个 `FLID` 一行 | 标量当前态、`OPERATION_DAY`、`STATE_VERSION`、最近消息 ID |
|
|
|
|
|
|
| 8 张资源明细表 | 每个 `FLID` 多行 | 登机门、值机柜台、行李转盘、计划机位、滑槽、延误、靠撤桥、轮挡 |
|
|
|
|
|
|
| `FLIGHT_ROUTE_POINT` | 每个 `FLID` 多行 | ROUT/ERUT 路线点,以 `ROUTE_KIND` 区分 |
|
|
|
|
|
|
| `SCHD_GEN` | 每个运营日一行 | `VERSION`、`LAST_MESSAGE_ID`、`LAST_RECV_AT`(上次提交时刻) |
|
|
|
|
|
|
| `SCHD_GEN_FLID` | 每个运营日、每个 `FLID` 一行 | 该日最新一代快照的完整名单,差删依据 |
|
2026-09-09 11:43:34 +08:00
|
|
|
|
| `PIPELINE_LOCK` | 单行 | 串行化状态写事务 |
|
2026-09-09 14:54:54 +08:00
|
|
|
|
| `PROC_STATE` | 每条消息一行 | 处理状态与重试结果 |
|
|
|
|
|
|
| `MSG_EVENT`(outbox) | 每个待投递事件一行 | 状态事件、变更通知、删除通知 |
|
|
|
|
|
|
| `REQ_TRACK` / `COUTMSGS` | 每个请求一行 | 请求状态与请求出站 |
|
|
|
|
|
|
| `BACKFILL_TODO` | 每个待补偿回填一行 | 共享信箱回填任务 |
|
|
|
|
|
|
| `SCHD_SNAP_LOG` | 每份快照一行 | 只追加快照留痕,不参与决策(§5.6) |
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
9 张明细表承载 10 类集合(ROUT 与 ERUT 共用路线表);`ORDINAL` 保留输入顺序,`SOURCE_SEQ` 只存上游序号,不作唯一键或去重键。
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
数据分三层,职责不得串用:**决策层**(上表除 `SCHD_SNAP_LOG` 外的表)承担正确性;**留痕层**(`SCHD_SNAP_LOG`)只追加、可丢弃重建;**证据层**(原始报文归档)冷路径、仅用于重演与审计,**尚未交付**。
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
### 3.3 完整当前态
|
|
|
|
|
|
|
|
|
|
|
|
主行 + 该 `FLID` 在 9 张明细表中的全部记录 = 完整当前态。写入前先在内存生成完整新状态再落库,明细集合按组先删后插。展示视图是投影,不是权威,也不能用于完整比对。
|
|
|
|
|
|
|
|
|
|
|
|
### 3.4 代码共享与过站
|
|
|
|
|
|
|
|
|
|
|
|
- 主航班与代码共享航班是各自独立的实例,各有 `FLID`,AODB 分别发记录与 FLOP。
|
|
|
|
|
|
- 共享航班用 `CSOP`、`CSFT` 指向主航班承运人代码与航班号;`MAFL` 存共享航班列表。
|
|
|
|
|
|
- `TAOP` / `TAFL` / `TAID` 是过站关联(进港与后续出港),不是代码共享。
|
|
|
|
|
|
- 删除时共享航班的 FDEL 先于主航班;本模块按 `FLID` 各自处理,不做级联推断。
|
|
|
|
|
|
|
|
|
|
|
|
### 3.5 运营日
|
|
|
|
|
|
|
|
|
|
|
|
`OPERATION_DAY` 是运行保障意义上的日期,不是报文接收日或落库日。
|
|
|
|
|
|
|
|
|
|
|
|
- `DNLD`/`RESP`:取快照覆盖运营日。
|
|
|
|
|
|
- `FLOP`:保留当前值。
|
|
|
|
|
|
- `ADFT` 或先于快照到达的 `FLOP`:暂为 `NULL`,被快照收录时补齐。
|
|
|
|
|
|
|
|
|
|
|
|
`NULL` 只表示尚未取得。延误跨日的航班仍是同一 `FLID`、运营日不变,由 FLOP 继续更新——SIS §3.16 注释 1 明确日计划不含前日延误航班,保留与清理由本模块负责。
|
|
|
|
|
|
|
|
|
|
|
|
## 4. 快照账本
|
|
|
|
|
|
|
|
|
|
|
|
主表一行只记当前状态与归属,答不了三件事:上一份快照包含哪些航班、最近一份快照是不是重放、并发推进有没有冲突。所以每个运营日另用两张表:
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
|
|
|
|
|
```text
|
2026-09-09 14:54:54 +08:00
|
|
|
|
SCHD_GEN 保存当前快照版本、最近消息 ID、上次提交时刻
|
|
|
|
|
|
SCHD_GEN_FLID 保存当前快照的完整 FLID 名单(管辖范围,不是归属)
|
2026-09-09 10:47:03 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
- `SCHD_GEN.VERSION` 是运营日快照版本;`FLIGHT_SCHD.STATE_VERSION` 是单航班状态版本,FLOP 只推进后者。
|
|
|
|
|
|
- 名单记管辖范围(这份快照管了谁),不是归属:一个 `FLID` 只出现在一个运营日的名单下,各日名单互不相交。
|
|
|
|
|
|
- 同一运营日可收多份快照:每次成功提交替换名单并版本加一;失败或最近快照重放不加版本。
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
## 5. 快照处理
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
设快照覆盖运营日 `D`,消息 ID `M`,记录集合 `R`,新成员集 `N = {record.FLID | record ∈ R}`,上一版成员集 `O`。两条前提:
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
|
|
|
|
|
```text
|
2026-09-09 14:54:54 +08:00
|
|
|
|
同一 FLID → 一个航班运行实例 → 一个运营日
|
|
|
|
|
|
同一 FLNO + 不同运营日 → 不同 FLID
|
2026-09-09 10:47:03 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
因此:**`FLID` 不跨日迁移;`OPERATION_DAY` 一经确定不可改;不同运营日的快照互不接管对方航班。**
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
### 5.1 处理步骤(同一事务)
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
1. 锁定 `PIPELINE_LOCK` 与 `SCHD_GEN(OPERATION_DAY=D)`。
|
|
|
|
|
|
2. `M = LAST_MESSAGE_ID` → 最近快照重放:不改状态、名单、版本、事件,直接记成功。
|
|
|
|
|
|
3. 校验完整性与覆盖范围(§5.2);任一失败整包不落地。
|
|
|
|
|
|
4. 校验 N 中每个 `FLID` 的既有 `OPERATION_DAY`(§5.3)。
|
|
|
|
|
|
5. 计算差删集合 `O − N`。
|
|
|
|
|
|
6. 按完整快照语义写入 N 中每个航班(§5.4)。
|
|
|
|
|
|
7. 删除 `O − N`,删除前断言 `OPERATION_DAY = D`。
|
|
|
|
|
|
8. 用 N 替换 `SCHD_GEN_FLID(D)` 名单。
|
|
|
|
|
|
9. CAS:`SCHD_GEN.VERSION = V + 1`,记录 `M`。
|
|
|
|
|
|
10. 登记状态事件、删除事件与处理终态。
|
|
|
|
|
|
11. 提交。
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
任一步失败:航班状态、成员名单、快照版本、删除结果、待发事件、处理终态全部回滚。
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
### 5.2 校验与覆盖范围
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
六项校验:`RECS` 在 0–9999;`RECS` 等于实收 `FLTR` 数;每条记录含合法数字型 `FLID`;快照内 `FLID` 不重复;每条记录运营日 = `D`;覆盖单个完整运营日。
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
覆盖范围按“是否为单个完整运营日”判定,与报文子类型无关(SIS §3.16 Data Range):
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
| 来源 | 覆盖范围 | 换代与差删 |
|
|
|
|
|
|
|---|---|---|
|
|
|
|
|
|
| 按单运营日请求得到的日计划 | 该日完整成员集 | 是 |
|
|
|
|
|
|
| AODB 定时下发的日计划 | 未来约 48 小时,跨多个运营日 | 否,只覆盖状态 |
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
判定落在接入侧:请求时指定单日,或按 `SODT` 分组并确认该组覆盖完整运营日。字段完整性与名单覆盖是两件事——窗口快照里每条记录仍是该 `FLID` 的完整字段状态,只是名单不完整。
|
|
|
|
|
|
|
|
|
|
|
|
### 5.3 航班归属
|
|
|
|
|
|
|
|
|
|
|
|
| 主行情况 | 处理 |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| 不存在 | 创建,`OPERATION_DAY = D` |
|
|
|
|
|
|
| `NULL` | 首次确定为 `D` |
|
|
|
|
|
|
| `= D` | 不变,按快照更新状态 |
|
|
|
|
|
|
| `≠ D` | 违反身份约束:不改写、整包拒绝、告警 `SAME_FLID_ACROSS_OPERATION_DAYS` |
|
|
|
|
|
|
|
|
|
|
|
|
第四行在合法流程不会出现,它意味着串日、错发或数据污染。既不静默保留(会掩盖错误),也不迁移归属(业务上没有这个动作):整包拒绝后交人工确认。
|
|
|
|
|
|
|
|
|
|
|
|
### 5.4 字段语义
|
|
|
|
|
|
|
|
|
|
|
|
| 输入 | 字段缺失含义 |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| `DNLD`/`RESP` 快照 | AODB 没有该数据 → 清除本地旧值 |
|
|
|
|
|
|
| `FLOP` 动态事件 | 本次没改 → 保留本地值 |
|
|
|
|
|
|
| `KAFKA_SCHD` 整态 | 当前态没有该字段 → 消费者删除旧值 |
|
|
|
|
|
|
|
|
|
|
|
|
写入规则:标量出现 Set、缺失 Clear;集合出现 Replace、缺失 Replace 空集。清除只对本模块正式映射的字段执行,声明不消费的字段忽略。
|
|
|
|
|
|
|
|
|
|
|
|
### 5.5 差删
|
|
|
|
|
|
|
|
|
|
|
|
差删集合就是 `O − N`。`OPERATION_DAY = D` 是删除前必须成立的校验,不是过滤后静默跳过的条件:
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
2026-09-09 11:43:34 +08:00
|
|
|
|
```text
|
2026-09-09 14:54:54 +08:00
|
|
|
|
for flid in (O − N):
|
|
|
|
|
|
if not exists(flid): continue # 已删除或幂等重放
|
|
|
|
|
|
if flight.OPERATION_DAY != D: fail # 账本或主表不一致,整包失败并告警
|
|
|
|
|
|
删除明细与主行;登记删除事件
|
2026-09-09 11:43:34 +08:00
|
|
|
|
```
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
出现 `OPERATION_DAY ≠ D` 是数据一致性错误,不是合法跨日场景。名单同时是差删的安全边界:不在 `O` 内的航班不删——少删可由下一次快照补上,多删不可自愈;账本不存在时不执行差删。`RECS=0` 的空快照仍会提交,旧名单中属于 D 的航班全部进入差删。
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
### 5.6 时序与留痕
|
2026-09-09 11:43:34 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
快照完整不等于无条件覆盖后来的动态事件。“快照是否比当前状态旧”需要一个跨 SCHD 与 FLOP 可比较的上游顺序,而 `SEQN` 不是:它由消息服务器分配,服务器不重启时不重复且单调递增,**重启后不可比**,也不表达业务新旧。
|
2026-09-09 11:43:34 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
因此当前**不启用陈旧拦截**,按信箱接收顺序处理;`SEQN` 只用于同一会话内的顺序观测(序号下降即记 `SEQN_REGRESSION` 并告警)。“快照最高权威”不是已成立的不变量,不得对外承诺。
|
2026-09-09 11:43:34 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
主链路失败即整体回滚,外部看不见系统做过什么,所以在事务之外只追加一条 `SCHD_SNAP_LOG`:
|
2026-09-09 11:43:34 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
| 字段 | 说明 |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| `OPERATION_DAY` / `MSG_ID` / `RECV_AT` | 运营日、消息 ID、接收时刻(UTC) |
|
|
|
|
|
|
| `RECS` / `OLD_VERSION` / `NEW_VERSION` / `DELETED_COUNT` | 规模与结果 |
|
|
|
|
|
|
| `RESULT` | `COMMITTED` / `REPLAY_SKIPPED` / `ROLLED_BACK` |
|
|
|
|
|
|
| `FLAGS` | `EMPTY` / `RECS_DROP` / `OUT_OF_ORDER` / `SEQN_REGRESSION` / `DAY_MISMATCH` |
|
|
|
|
|
|
| `OLD_FLID_DIGEST` / `NEW_FLID_DIGEST` | 新旧名单指纹,审计名单抖动 |
|
|
|
|
|
|
| `ARCHIVE_KEY` / `DURATION_MS` | 原文归档引用与耗时 |
|
2026-09-09 11:43:34 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
规则:
|
2026-09-09 11:43:34 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
- `RESULT` 与 `FLAGS` 分列:一次提交可以同时“成功”且“触发告警”。
|
|
|
|
|
|
- 一行 = 一次处理尝试;不建 `(OPERATION_DAY, MSG_ID)` 唯一键,重放也记一行。
|
|
|
|
|
|
- 留痕不参与任何决策:写失败只记 error 指标,不改变已提交事务的结果;留痕成功也不代表事务成功。
|
|
|
|
|
|
- 观测告警与状态变更同一事务登记,避免“异常已提交但告警丢失”或反向错配。`DAY_MISMATCH` 即 §5.3 的归属不符。
|
|
|
|
|
|
- 保留 90 天,按 `(OPERATION_DAY, RECV_AT)` 清理。
|
2026-09-09 11:43:34 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
## 6. 动态事件与删除
|
2026-09-09 11:43:34 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
### 6.1 FLOP
|
2026-09-09 11:43:34 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
FLOP 不建立快照也不改名册:读取完整当前态 → 合并本次变化 → 保留运营日(无则 `NULL`)→ `STATE_VERSION` 加一 → 同事务登记 `KAFKA_MSG`、`KAFKA_SCHD` 与处理结果。
|
2026-09-09 11:43:34 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
### 6.2 FDEL
|
2026-09-09 11:43:34 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
FDEL 表示 AODB 终止某个航班运行实例(SIS §3.29)。它与快照差删是两个入口,对外事件形态一致。同一事务内:
|
2026-09-09 11:43:34 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
1. 按 `FLID` 定位;不存在视为幂等成功(迟到、重复不报错)。
|
|
|
|
|
|
2. 删除主行与 9 张明细表。
|
|
|
|
|
|
3. 从该 `FLID` 所属运营日的 `SCHD_GEN_FLID` 名单中移除它——否则该日下一次快照还会把它算进 `O − N`。
|
|
|
|
|
|
4. 登记删除事件与处理终态。
|
2026-09-09 11:43:34 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
FDEL 不推进 `SCHD_GEN.VERSION`、不改 `LAST_MESSAGE_ID`、不触发差删。共享航班的 FDEL 先于主航班到达,按 `FLID` 各自处理,不做级联推断。
|
2026-09-09 11:43:34 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
## 7. 对外处理
|
2026-09-09 11:43:34 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
### 7.1 请求
|
2026-09-09 11:43:34 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
请求经 `REQ_TRACK` 登记、`COUTMSGS` 发出;同类请求只保留一条有效,新请求把旧的置为 `EXPIRED`。`RESP` 按(运营日、发送方、请求类型)完成最新一条 `PENDING`;`DNLD` 仅在运营日匹配时完成请求。协议没有请求关联号,匹配规则仍需验收。
|
2026-09-09 11:43:34 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
差删只认覆盖单个完整运营日的快照,所以本模块必须**为每个运营日至少主动请求一次完整日计划**。当前请求出站尚未完成,实际只收到定时下发的 48 小时窗口,**差删因此没有合法输入、名单只增不删**——这是现状,不是目标。
|
2026-09-09 11:43:34 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
### 7.2 回填
|
2026-09-09 11:43:34 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
事务提交后回填共享信箱;回填失败不得把已提交的 `SUCCEEDED` 改回 `FAILED`。
|
2026-09-09 11:43:34 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
### 7.3 Kafka
|
2026-09-09 11:43:34 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
`KAFKA_SCHD` 发航班整态,不是补丁:Dispatcher 合并同一 `FLID` 的未发事件,按最新 `STATE_VERSION` 输出,中间版本不逐条发送。`KAFKA_MSG` 只通知变化。两个主题之间不保证顺序。整态里键缺失表示该数据不存在,消费者应删除旧值。
|
2026-09-09 11:43:34 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
判旧方式:消费端 `(FLID, STATE_VERSION, UPDATED_AT)`;日代侧 `(OPERATION_DAY, VERSION)`,`VERSION` 只在单运营日内单调,不得裸比较。
|
2026-09-09 11:43:34 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
删除用 tombstone:value 非 null,载荷至少含 `FLID`、`STATE_VERSION`、`DELETED`;与删除操作同事务登记,投递失败持续重试。即使将来确认 `FLID` 永不复用,`STATE_VERSION` 也不能省——同一 `FLID` 的更新与删除事件仍会乱序。
|
2026-09-09 11:43:34 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
### 7.4 身份不变量
|
2026-09-09 11:43:34 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
- `FLIGHT_SCHD.FLID` 是主键,`OPERATION_DAY` 可空。
|
|
|
|
|
|
- 一个 `FLID` 最多一个非空 `OPERATION_DAY`,且一经确定不得修改。
|
|
|
|
|
|
- 同 `FLNO` 不同运营日 = 不同 `FLID`,各自独立存储。
|
|
|
|
|
|
- 状态合并、`STATE_VERSION`、明细集合、Kafka 事件都以 `FLID` 为边界。
|
|
|
|
|
|
- 不允许通过航班号或日期推断两个 `FLID` 是同一实例。
|
|
|
|
|
|
- FDEL + ADFT 是旧实例终止与新实例建立,不是主键变更。
|
|
|
|
|
|
|
|
|
|
|
|
`OPERATION_DAY` 不可变由应用层在快照入口校验;要数据库层强化,可加触发器或把更新写成 `WHERE operation_day IS NULL OR operation_day = :d`。
|
|
|
|
|
|
|
|
|
|
|
|
## 8. 生命周期与清理
|
|
|
|
|
|
|
|
|
|
|
|
运营日过去不等于航班结束:可能延误、跨日运行、返航或仍在收动态,不能在午夜按日期删除。
|
|
|
|
|
|
|
|
|
|
|
|
### 8.1 历史判定
|
|
|
|
|
|
|
|
|
|
|
|
满足任一条件即判为历史(默认值可配,未接线前不生效):
|
|
|
|
|
|
|
|
|
|
|
|
- 计划开始时间 `SODT` 超过 48 小时;
|
|
|
|
|
|
- 取消(`CNCL` 非空)超过 48 小时;
|
|
|
|
|
|
- 备降航班已结束本场处理(判定字段待确认,未确认前该条不生效);
|
|
|
|
|
|
- 离港关门 `NAAT` 超过 48 小时;
|
|
|
|
|
|
- 到港下机完成 `NEAT` 超过 48 小时。
|
|
|
|
|
|
|
|
|
|
|
|
窗口按 `SODT` 所属运营日、机场本地时区(Asia/Shanghai)计算,不按落库日或 UTC 日期。
|
|
|
|
|
|
|
|
|
|
|
|
### 8.2 归档与清除(顺序不可颠倒)
|
|
|
|
|
|
|
|
|
|
|
|
1. `HISTORY_SWEEP` 选出已结束航班。
|
|
|
|
|
|
2. 写入历史存储。
|
|
|
|
|
|
3. 历史存储返回成功的 `FLID` 集合。
|
|
|
|
|
|
4. 只删除该集合对应的主行与明细。
|
|
|
|
|
|
5. 登记对外删除事件。
|
|
|
|
|
|
6. 失败或不明确的继续保留,下次重试。
|
|
|
|
|
|
|
|
|
|
|
|
历史存储未接通时成功集合为空,必须删 0 条;绝不允许先删当前态再补历史。
|
|
|
|
|
|
|
|
|
|
|
|
### 8.3 保留期与清理
|
|
|
|
|
|
|
|
|
|
|
|
| 对象 | 默认保留 | 清理前置条件 |
|
|
|
|
|
|
|---|---|---|
|
|
|
|
|
|
| 账本 `SCHD_GEN` / `SCHD_GEN_FLID` | cutoff = 今天 − 7 天 | 该日无未终态消息与未清回填;该日待归档航班已写入历史;不破坏仍在使用的差删依据 |
|
|
|
|
|
|
| 留痕 `SCHD_SNAP_LOG` | 90 天 | 按 `(OPERATION_DAY, RECV_AT)` 清理 |
|
|
|
|
|
|
| `OPERATION_DAY = NULL` 航班 | 7 天 | 仍未被任何快照收录;终止规则未定前只增不删 |
|
|
|
|
|
|
|
|
|
|
|
|
删除 `SCHD_GEN` 时外键级联删除该日名单。未配置 cutoff 时不清理。
|
2026-09-09 11:43:34 +08:00
|
|
|
|
|
|
|
|
|
|
## 9. 失败与读取
|
|
|
|
|
|
|
|
|
|
|
|
| 错误 | 处理 | 队头行为 |
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|---|---|---|
|
2026-09-09 11:43:34 +08:00
|
|
|
|
| 非法报文、数量不符、容量超限 | `DEAD`,不重试 | 立即释放 |
|
2026-09-09 14:54:54 +08:00
|
|
|
|
| 未支持类型 | `FAILED(UNSUPPORTED)` | 达阈值转 `DEAD` |
|
2026-09-09 11:43:34 +08:00
|
|
|
|
| 数据库或内部故障 | `FAILED(INFRA)`,退避重试 | 成功或超限前阻塞 |
|
2026-09-09 14:54:54 +08:00
|
|
|
|
| 快照 CAS 冲突 | 回滚重读重试 | 成功前阻塞 |
|
|
|
|
|
|
| 快照含归属日不符的 `FLID` | 整包拒绝 `DEAD(PROTOCOL)`,留痕告警 | 立即释放,交人工确认 |
|
|
|
|
|
|
| `SEQN` 回退(同会话内序号下降) | 只记 `FLAGS` 并告警 | 不阻塞 |
|
|
|
|
|
|
| 留痕写失败 | 只记 error 指标,不改变已提交结果 | 不阻塞 |
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
读取:完整航班状态必须在一致性读事务中读主表与全部明细表。当前逐航班读取有 N+1 问题,且主表与明细可能不在同一数据库快照——批量加载与一致性读边界待补。
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
## 10. 未定事项
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
由 ACM2-31 跟踪:快照与动态事件顺序、FLOP 集合语义、删除事件版本、幂等键生命周期、FIFO 参数、一致性读取、快照完整性校验、Oracle 适配。
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
| 事项 | 状态 |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| `FLID` 与运营日绑定、不跨日迁移 | 已定案(§3.1、§5.3);原 ACM2-31#9 改为入口身份一致性校验 |
|
|
|
|
|
|
| 日计划覆盖范围按“是否单日完整”判定 | 已定案(§5.2) |
|
|
|
|
|
|
| `SEQN` 可用边界 | 已明确:服务器不重启时单调,重启后不可比(§5.6);唯一范围与回绕未定义(ACM2-31#12) |
|
|
|
|
|
|
| `FLID` 是否会被复用 | **待上游书面确认**;确认前删除与恢复设计不能只依赖 `FLID` |
|
|
|
|
|
|
| 备降“已结束本场处理”的判定字段 | 待确认(§8.1) |
|
|
|
|
|
|
| 逐运营日请求完整日计划 | 未完成;在此之前差删无合法输入(§7.1) |
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
当前偏差:GTDT 按登机门集合 Replace 处理,但 FLOP 集合语义未确认;动态事件在锁外生成事件预览、事务内再算一次,目标是只算一次;回填待办在提交后写,崩溃窗口内不可恢复,目标是事务内预登记。
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
### 规则 M:快照与动态事件的优先级
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
同一运营日内,完整快照覆盖此前动态事件写入的重叠字段;快照未出现的字段按快照语义清除。该规则要求投递顺序等于上游发送顺序,协议尚未证明,因此它不是已成立的不变量,不得对外承诺(ACM2-31#8)。
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
### 规范依据(SIS)
|
2026-09-09 10:47:03 +08:00
|
|
|
|
|
2026-09-09 14:54:54 +08:00
|
|
|
|
| 结论 | 出处 |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| 以 AODB 最新数据覆盖本地 | §1.6.2 |
|
|
|
|
|
|
| `P` 标签为空 = 删除该值;`O` 标签仅在有值时出现 | §1.6.3 |
|
|
|
|
|
|
| 日计划是完整快照;未发送的可选字段表示 AODB 已无该数据,应删除 | §3.16 注释 2、4 |
|
|
|
|
|
|
| 子系统不消费的字段可忽略 | §3.16 注释 3 |
|
|
|
|
|
|
| 日计划不含前日延误航班,保留与清理由子系统负责 | §3.16 注释 1 |
|
|
|
|
|
|
| 主动下发为未来约 48 小时窗口,请求应答按请求范围 | §3.16 Data Range |
|
|
|
|
|
|
| 代码共享为独立航班实例,删除时共享先于主航班 | §1.6.5 |
|