docs: remove retired schedule generation design
This commit is contained in:
@@ -1,11 +1,11 @@
|
|||||||
# msgexchange-v2(机场上游报文处理中间件)
|
# msgexchange-v2(机场上游报文处理中间件)
|
||||||
|
|
||||||
**系统角色**:消费 CIIMS/AODB 等上游经共享 MySQL 信箱(`CMINMSGS`)投递的 XML 报文,
|
**系统角色**:消费 CIIMS/AODB 等上游经共享 MySQL 信箱(`CMINMSGS`)投递的 XML 报文,
|
||||||
解析处理后维护 Redis 航班动态并向 Kafka / 出站信箱投递——**中间件**,非报文源系统。
|
解析处理后维护自有 PostgreSQL 航班当前态并向 Kafka / 出站信箱投递——**中间件**,非报文源系统。
|
||||||
|
|
||||||
依据 **ACMA-8 v4 综合架构**(单写者严格 FIFO 管道)与 **ACMA-6 技术选型**
|
依据 **ACMA-8 v4 综合架构**(单写者严格 FIFO 管道)与 **ACMA-6 技术选型**
|
||||||
(Micronaut 5.1 + Kotlin 2.3)搭建;**存储边界与阶段 B 按 ACM2-11/ACM2-12 定案**
|
(Micronaut 5.1 + Kotlin 2.3)搭建;**存储边界与阶段 B 按 ACM2-11/ACM2-12 定案**
|
||||||
(自有 PostgreSQL 全内部状态 + 共享 MySQL 仅信箱 + Redis 动态/gen,阶段 B 缓做)。
|
(自有 PostgreSQL 维护内部状态,共享 MySQL 仅作信箱边界)。
|
||||||
本仓库独立于 legacy `msgexchange-api`(Java 8 / Spring Boot 1.5 / Maven)——
|
本仓库独立于 legacy `msgexchange-api`(Java 8 / Spring Boot 1.5 / Maven)——
|
||||||
过渡期两套系统并存(影子对拍→切流→旧仓库冻结),legacy 维护不受本仓库影响。
|
过渡期两套系统并存(影子对拍→切流→旧仓库冻结),legacy 维护不受本仓库影响。
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
|---|---|---|
|
|---|---|---|
|
||||||
| **入站(主路径)** | JDBC 轮询共享 `CMINMSGS` | 上游经 CIIMS 等**外部系统**写信箱;本系统 1s 轮询 `DATE_PROCESSED IS NULL` 发现新信 → 自有 PG 入队(`InboxPoller`,U05) |
|
| **入站(主路径)** | JDBC 轮询共享 `CMINMSGS` | 上游经 CIIMS 等**外部系统**写信箱;本系统 1s 轮询 `DATE_PROCESSED IS NULL` 发现新信 → 自有 PG 入队(`InboxPoller`,U05) |
|
||||||
| **入站(compat)** | HTTP `POST /cminmsgs/send` | 手工注入/影子对拍;写信箱 + PG 入队,**非**生产主拓扑 |
|
| **入站(compat)** | HTTP `POST /cminmsgs/send` | 手工注入/影子对拍;写信箱 + PG 入队,**非**生产主拓扑 |
|
||||||
| **处理** | 主泵 FIFO 管道 | 解码 → identity → Handler 决策 → Redis 动态权威态 |
|
| **处理** | 主泵 FIFO 管道 | 解码 → identity → Handler 决策 → PostgreSQL 航班当前态 |
|
||||||
| **出站** | Kafka + `COUTMSGS` | 向下游推送 msg/schd;请求类报文写出站信箱 |
|
| **出站** | Kafka + `COUTMSGS` | 向下游推送 msg/schd;请求类报文写出站信箱 |
|
||||||
|
|
||||||
与 SIS / legacy 一致:本系统**不**替代 CIIMS 落信,**不**生成原始 AODB 业务报文。
|
与 SIS / legacy 一致:本系统**不**替代 CIIMS 落信,**不**生成原始 AODB 业务报文。
|
||||||
@@ -36,17 +36,14 @@
|
|||||||
| `codec/` | SIS XML codec(注解 wire DTO → 领域载荷,禁 DTD/外部实体) | 决策 4 前置 |
|
| `codec/` | SIS XML codec(注解 wire DTO → 领域载荷,禁 DTD/外部实体) | 决策 4 前置 |
|
||||||
| `domain/` | 领域模型:Decision、事件、状态机枚举、Phase 开关 | I1–I5 |
|
| `domain/` | 领域模型:Decision、事件、状态机枚举、Phase 开关 | I1–I5 |
|
||||||
| `config/` | `PipelineProps` 参数表(ACMA-8 参数初值,`msgx.*`) | — |
|
| `config/` | `PipelineProps` 参数表(ACMA-8 参数初值,`msgx.*`) | — |
|
||||||
| `infra/` | 仓储接口、Redis Lua 装载、stub、健康、重试策略 | 数据模型节 |
|
| `infra/` | 仓储接口、stub、健康、重试策略 | 数据模型节 |
|
||||||
|
|
||||||
## 资源
|
## 资源
|
||||||
|
|
||||||
- `docs/legacy/SIS_AODB_RMS-V0.1.md` + `docs/legacy/unisysaodbsis.xsd`:**消息结构唯一事实源**
|
- `docs/legacy/SIS_AODB_RMS-V0.1.md` + `docs/legacy/unisysaodbsis.xsd`:**消息结构唯一事实源**
|
||||||
(wire 契约冻结,自 legacy 仓库复制以自包含;codec 实装依据,ACM2-2/ACM2-3)。
|
(wire 契约冻结,自 legacy 仓库复制以自包含;codec 实装依据,ACM2-2/ACM2-3)。
|
||||||
- `db/migration/V1.0.0__own_pg_pipeline.sql`:**自有 PostgreSQL**(唯一自有库)表结构
|
- `db/migration/V1__flight_state_baseline.sql`:**自有 PostgreSQL**(唯一自有库)的航班状态与处理管道表结构;
|
||||||
(PROC_STATE / MSG_EVENT / PUMP_JOB / REQ_TRACK / REF_MASTER,PG 方言),ACM2-12 定案;
|
共享 MySQL(CMINMSGS/COUTMSGS)仅信箱 DML,不建表。
|
||||||
共享 MySQL(CMINMSGS/COUTMSGS)仅信箱 DML 不建表;快照 gen 与航班动态在 Redis。
|
|
||||||
- `lua/snapshot_replace.lua`:同一 hash 原子“覆盖新代 + 按代差删”(流程 4,I4/I5;
|
|
||||||
随 gen→Redis 协议(U09)扩展版本推进)。
|
|
||||||
- `lua/batch_delete.lua`:3:30 清场批量删除(仅 ES 写成功集,I4)。
|
- `lua/batch_delete.lua`:3:30 清场批量删除(仅 ES 写成功集,I4)。
|
||||||
- `application.yml`:口令全部环境变量外置(零入库);`datasources.default`=自有 PG(enabled=false
|
- `application.yml`:口令全部环境变量外置(零入库);`datasources.default`=自有 PG(enabled=false
|
||||||
待 U05)、`mailbox.shared-mysql`=共享信箱;`msgx.phase` 权威口径(A 现役;B 缓做);
|
待 U05)、`mailbox.shared-mysql`=共享信箱;`msgx.phase` 权威口径(A 现役;B 缓做);
|
||||||
@@ -66,9 +63,8 @@
|
|||||||
|
|
||||||
## 数据库初始化(ACM2-12 口径)
|
## 数据库初始化(ACM2-12 口径)
|
||||||
|
|
||||||
**自有 PostgreSQL**(唯一自有库):`db/migration/V1.0.0__own_pg_pipeline.sql` 建
|
**自有 PostgreSQL**(唯一自有库):Flyway 执行 `db/migration/V1__flight_state_baseline.sql`,建立
|
||||||
PROC_STATE / MSG_EVENT / PUMP_JOB / REQ_TRACK / REF_MASTER(PG 方言)。全新库直接执行即可,
|
航班当前态、明细表、处理终态与 outbox 等表(PG 方言)。全新库直接执行即可,无 legacy 前置。
|
||||||
无 legacy 前置。
|
|
||||||
|
|
||||||
**共享 MySQL(cdairport,他人系统库)**:本系统**不建表/schema**,仅信箱 DML——上游外部写
|
**共享 MySQL(cdairport,他人系统库)**:本系统**不建表/schema**,仅信箱 DML——上游外部写
|
||||||
`CMINMSGS`;本系统 JDBC 轮询读 + 处理回填;出站写 `COUTMSGS`(他人读取发送);表结构与
|
`CMINMSGS`;本系统 JDBC 轮询读 + 处理回填;出站写 `COUTMSGS`(他人读取发送);表结构与
|
||||||
@@ -77,8 +73,7 @@ PROC_STATE / MSG_EVENT / PUMP_JOB / REQ_TRACK / REF_MASTER(PG 方言)。全
|
|||||||
- **事务模型**:与共享库交互均为外部副作用(ACM2-12)——主路径=上游外部写信箱 →
|
- **事务模型**:与共享库交互均为外部副作用(ACM2-12)——主路径=上游外部写信箱 →
|
||||||
JDBC 轮询发现新信 → 自有 PG 建 PENDING 入队(失败重扫补建);HTTP `/cminmsgs/send`
|
JDBC 轮询发现新信 → 自有 PG 建 PENDING 入队(失败重扫补建);HTTP `/cminmsgs/send`
|
||||||
为 compat 写路径;处理成功回填 DATE_PROCESSED/STATUS 为最终一致。
|
为 compat 写路径;处理成功回填 DATE_PROCESSED/STATUS 为最终一致。
|
||||||
- **快照 gen**:随航班动态同在 Redis(gen→Redis 协议属 U09,当前为过渡占位)。
|
- **航班状态**:写入自有 PostgreSQL;完整规则见 `docs/flight-state.md`。
|
||||||
- **阶段 B(FLIGHT_STATE)**:缓做不落表。
|
|
||||||
- 影子对拍:自有 PG 开独立 schema;共享信箱为单信箱无法双写,影子输入=只读水位/回放口径。
|
- 影子对拍:自有 PG 开独立 schema;共享信箱为单信箱无法双写,影子输入=只读水位/回放口径。
|
||||||
|
|
||||||
|
|
||||||
@@ -86,8 +81,8 @@ PROC_STATE / MSG_EVENT / PUMP_JOB / REQ_TRACK / REF_MASTER(PG 方言)。全
|
|||||||
|
|
||||||
仓库根目录提供兼容 Podman Compose 与 Docker Compose 的开发中间件栈 `compose.yaml`,包含:
|
仓库根目录提供兼容 Podman Compose 与 Docker Compose 的开发中间件栈 `compose.yaml`,包含:
|
||||||
- **共享信箱 MySQL**(`mysql:8.4` LTS,端口 3306,库 `cdairport`):容器启动时自动执行 `deploy/dev/mysql-init/01-mailbox.sql` 创建本地联调所需的 `CMINMSGS`、`CMINMSGS_HST`、`COUTMSGS` 模拟表。
|
- **共享信箱 MySQL**(`mysql:8.4` LTS,端口 3306,库 `cdairport`):容器启动时自动执行 `deploy/dev/mysql-init/01-mailbox.sql` 创建本地联调所需的 `CMINMSGS`、`CMINMSGS_HST`、`COUTMSGS` 模拟表。
|
||||||
- **自有 PostgreSQL**(`postgres:17-alpine`,端口 5432,库 `msgx`):容器提供干净数据库,应用启动时由 Flyway(`db/migration/V1.0.0__own_pg_pipeline.sql`)自动建自有表。
|
- **自有 PostgreSQL**(`postgres:17-alpine`,端口 5432,库 `msgx`):容器提供干净数据库,应用启动时由 Flyway(`db/migration/V1__flight_state_baseline.sql`)自动建自有表。
|
||||||
- **Redis / 动态与快照**(开源分叉 `valkey/valkey:8-alpine`,端口 6379):100% 兼容 Redis 7.2+ 协议与 Lua 脚本,支持 `--appendonly yes`。
|
- **Valkey**(`valkey/valkey:8-alpine`,端口 6379):本地中间件兼容服务,不承担航班状态权威或日计划处理。
|
||||||
- **Kafka**(`apache/kafka:3.8.0` KRaft 单节点,端口 9092):listener `PLAINTEXT://localhost:9092`,`default.replication.factor=1`,已预配幂等生产者与 acks=all 所需的单节点参数。
|
- **Kafka**(`apache/kafka:3.8.0` KRaft 单节点,端口 9092):listener `PLAINTEXT://localhost:9092`,`default.replication.factor=1`,已预配幂等生产者与 acks=all 所需的单节点参数。
|
||||||
|
|
||||||
### 快速启动
|
### 快速启动
|
||||||
@@ -169,7 +164,7 @@ MICRONAUT_ENVIRONMENTS=dev ./gradlew run # dev stub 冒烟:内存 stub,无
|
|||||||
- [docs/user-stories.md](docs/user-stories.md):阶段 A US-01~US-14、延后清场 US-15、上线 Epic、
|
- [docs/user-stories.md](docs/user-stories.md):阶段 A US-01~US-14、延后清场 US-15、上线 Epic、
|
||||||
legacy HTTP 去留及逐项文档 TODO;包含验收标准、依赖、实现差距与待确认问题。
|
legacy HTTP 去留及逐项文档 TODO;包含验收标准、依赖、实现差距与待确认问题。
|
||||||
(原 ACM2-15~22 文档整改清单 user-stories-todo.md 已收敛完成并移除,跟踪记录见 Plane。)
|
(原 ACM2-15~22 文档整改清单 user-stories-todo.md 已收敛完成并移除,跟踪记录见 Plane。)
|
||||||
- [docs/decision-flight-state.md](docs/decision-flight-state.md):有效决策摘要——单库权威已采纳,固定槽位方案已撤销;历史全文另存。
|
- [docs/flight-state.md](docs/flight-state.md):航班状态的唯一现行设计规范;历史方案不作为实现依据。
|
||||||
- [docs/legacy/](docs/legacy/):外部参考/基线材料(自 legacy 仓库拷贝,非本系统文档)——
|
- [docs/legacy/](docs/legacy/):外部参考/基线材料(自 legacy 仓库拷贝,非本系统文档)——
|
||||||
`msgexchange-api-legacy-user-stories.md`(legacy 行为对拍基线,ACMA-4)、`unisysaodbsis.xsd`、
|
`msgexchange-api-legacy-user-stories.md`(legacy 行为对拍基线,ACMA-4)、`unisysaodbsis.xsd`、
|
||||||
`SIS_AODB_RMS-V0.1.md`(消息结构唯一事实源;CIIMS 中间件交换模型)。
|
`SIS_AODB_RMS-V0.1.md`(消息结构唯一事实源;CIIMS 中间件交换模型)。
|
||||||
|
|||||||
+2
-2
@@ -6,9 +6,9 @@
|
|||||||
|---|---|
|
|---|---|
|
||||||
| [architecture.md](architecture.md) | 系统边界、模块职责、FIFO、单写者、数据库归属。 |
|
| [architecture.md](architecture.md) | 系统边界、模块职责、FIFO、单写者、数据库归属。 |
|
||||||
| [design.md](design.md) | 管道流程、处理/投递状态、恢复与运行配置。 |
|
| [design.md](design.md) | 管道流程、处理/投递状态、恢复与运行配置。 |
|
||||||
| [flight-state.md](flight-state.md) | 航班当前态、快照账本、表关系、事务流程和开放问题。 |
|
| [flight-state.md](flight-state.md) | 航班设计的唯一现行规范:当前态、表关系、事务流程和开放问题。 |
|
||||||
| [user-stories.md](user-stories.md) | US/OPS 验收目标,不能用“当前基础”替代完成证据。 |
|
| [user-stories.md](user-stories.md) | US/OPS 验收目标,不能用“当前基础”替代完成证据。 |
|
||||||
| [decision-flight-state.md](decision-flight-state.md) | 有效决策与理由,历史全文转入 legacy。 |
|
| [legacy/decision-flight-state-history.md](legacy/decision-flight-state-history.md) | 已撤销方案的存档说明;现行规则仍以 `flight-state.md` 为准。 |
|
||||||
| [SIS 规范](legacy/SIS_AODB_RMS-V0.1.md) / [XSD](legacy/unisysaodbsis.xsd) | 外部协议事实;即使在 legacy 目录仍是兼容依据。 |
|
| [SIS 规范](legacy/SIS_AODB_RMS-V0.1.md) / [XSD](legacy/unisysaodbsis.xsd) | 外部协议事实;即使在 legacy 目录仍是兼容依据。 |
|
||||||
|
|
||||||
维护规则:架构写约束,设计写机制,故事写目标,Plane 跟踪工作。不要在多份文档复制阶段清单。
|
维护规则:架构写约束,设计写机制,故事写目标,Plane 跟踪工作。不要在多份文档复制阶段清单。
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ msgexchange-v2 是机场 OMMS 的上游报文处理中间件,用于替换旧
|
|||||||
本文描述架构约束,不代表所有能力已实现;实现缺口见第 9 节。模块交互、状态机和参数详见 [design.md](design.md),需求见 [user-stories.md](user-stories.md)。历史报文契约仍以 [SIS 接口规范](legacy/SIS_AODB_RMS-V0.1.md) 和 [XSD](legacy/unisysaodbsis.xsd) 为兼容依据,其他 legacy 资料仅作参考。
|
本文描述架构约束,不代表所有能力已实现;实现缺口见第 9 节。模块交互、状态机和参数详见 [design.md](design.md),需求见 [user-stories.md](user-stories.md)。历史报文契约仍以 [SIS 接口规范](legacy/SIS_AODB_RMS-V0.1.md) 和 [XSD](legacy/unisysaodbsis.xsd) 为兼容依据,其他 legacy 资料仅作参考。
|
||||||
|
|
||||||
现场供库时目标为 Oracle 11g,否则自建 PostgreSQL;当前只有 PG 实现可运行,Oracle 不是已支持的平台。
|
现场供库时目标为 Oracle 11g,否则自建 PostgreSQL;当前只有 PG 实现可运行,Oracle 不是已支持的平台。
|
||||||
航班表结构、快照账本和处理逻辑见 [航班状态设计](flight-state.md)。
|
航班表结构和处理逻辑见 [航班状态设计](flight-state.md)。
|
||||||
|
|
||||||
## 2. 总体架构
|
## 2. 总体架构
|
||||||
|
|
||||||
@@ -147,4 +147,4 @@ CIIMS / AODB 等上游
|
|||||||
- 生产启动校验、单实例排他保护、影子隔离和 Kafka 配置约束;当前配置仍允许 Kafka 参数覆盖,且默认 in-flight 值与 D11 要求不同。
|
- 生产启动校验、单实例排他保护、影子隔离和 Kafka 配置约束;当前配置仍允许 Kafka 参数覆盖,且默认 in-flight 值与 D11 要求不同。
|
||||||
- 死信告警、人工重放、端到端追踪、积压指标及安全边界。
|
- 死信告警、人工重放、端到端追踪、积压指标及安全边界。
|
||||||
|
|
||||||
具体实现差异见 design.md §10 与 ACM2-29 核查报告,工作由 Plane 跟踪。有效存储决策见 decision-flight-state.md;历史阶段口径不覆盖当前规则。
|
具体实现差异见 design.md §10 与 ACM2-29 核查报告,工作由 Plane 跟踪。航班状态的有效规则统一见 flight-state.md;历史阶段口径不覆盖当前规则。
|
||||||
|
|||||||
+8
-10
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
本文说明模块如何协作、状态如何流转,以及失败后如何恢复。系统范围、存储归属和部署约束见 [architecture.md](architecture.md),不在这里重复。
|
本文说明模块如何协作、状态如何流转,以及失败后如何恢复。系统范围、存储归属和部署约束见 [architecture.md](architecture.md),不在这里重复。
|
||||||
|
|
||||||
阶段 A 采纳 ACM2-28 选项 C 定案:运营航班权威状态落自有 PostgreSQL(表 `FLIGHT_SCHD` 与 `SCHD_GEN`),Redis 彻底退出动态权威与全部写路径。阶段 B 的历史投影和清场暂不启用。
|
阶段 A 采纳 ACM2-28 选项 C 定案:运营航班权威状态落自有 PostgreSQL(`FLIGHT_SCHD` 及资源明细表),Redis 彻底退出动态权威与全部写路径。阶段 B 的历史投影和清场暂不启用。
|
||||||
|
|
||||||
本文的流程是验收目标,当前差异见 §10。航班状态设计统一由
|
本文的流程是验收目标,当前差异见 §10。航班状态设计统一由
|
||||||
[航班状态设计](flight-state.md) 维护。
|
[航班状态设计](flight-state.md) 维护。
|
||||||
@@ -22,15 +22,13 @@
|
|||||||
| `PUMP_JOB` | 持久化维护作业 | 状态为 `QUEUED / RUNNING / DONE / FAILED`;不与业务消息共用排序序号。 |
|
| `PUMP_JOB` | 持久化维护作业 | 状态为 `QUEUED / RUNNING / DONE / FAILED`;不与业务消息共用排序序号。 |
|
||||||
| `REQ_TRACK` | 上游请求及应答关联 | 保存请求类型、参数、出站信箱 ID、发送和完成时间;同类只允许一个开放请求。 |
|
| `REQ_TRACK` | 上游请求及应答关联 | 保存请求类型、参数、出站信箱 ID、发送和完成时间;同类只允许一个开放请求。 |
|
||||||
| `REF_MASTER` | 静态参考数据 | `(RTYPE, RKEY)` 唯一,`SOURCE` 记录数据来源。 |
|
| `REF_MASTER` | 静态参考数据 | `(RTYPE, RKEY)` 唯一,`SOURCE` 记录数据来源。 |
|
||||||
| `FLIGHT_SCHD` | 航班标量及单值异常、3 类文本载荷 | `FLID` 主键,`FDAY` 可空;版本和消息身份用于追踪。10 类重复集合存于 9 张明细表,见航班状态设计。 |
|
| `FLIGHT_SCHD` | 航班标量及单值异常、3 类文本载荷 | `FLID` 主键;运营日、版本和消息身份用于追踪。10 类重复集合存于 9 张明细表,见航班状态设计。 |
|
||||||
| `BACKFILL_TODO` | 共享信箱回填重试 | 当前失败后落账,终态与待办同事务持久化尚未完成。 |
|
| `BACKFILL_TODO` | 共享信箱回填重试 | 当前失败后落账,终态与待办同事务持久化尚未完成。 |
|
||||||
| `SCHD_GEN` | 日计划代版本(差删依据与版本 CAS) | `FDAY` 主键,`VERSION` 版本号,`TIMESTAMPTZ`。 |
|
|
||||||
| `SCHD_GEN_FLID` | 当前代有效航班 FLID 集合(原 `FLIDS_JSON` 展开为行) | `(FDAY, FLID)` 主键,`FDAY` 外键级联删除。 |
|
|
||||||
| `PROC_STATE_HST` | 终态处理记录的归档目标 | 属于目标设计,当前迁移尚未建表;不得改写为共享库历史表。 |
|
| `PROC_STATE_HST` | 终态处理记录的归档目标 | 属于目标设计,当前迁移尚未建表;不得改写为共享库历史表。 |
|
||||||
|
|
||||||
字段与索引定义以 `src/main/resources/db/migration/` 为准(含 `V1.1.0__flight_schd.sql`)。报文原文仍从共享信箱读取,因此必须协调原文保留期,不能在消息尚需处理或重放时提前清理。
|
字段与索引定义以 `src/main/resources/db/migration/` 为准(含 `V1.1.0__flight_schd.sql`)。报文原文仍从共享信箱读取,因此必须协调原文保留期,不能在消息尚需处理或重放时提前清理。
|
||||||
|
|
||||||
Redis 已彻底退出动态权威与写路径;`FLIGHT_SCHD` 与 `SCHD_GEN` 在自有 PG 中由主泵单线程独占写入。
|
Redis 已彻底退出动态权威与写路径;`FLIGHT_SCHD` 及资源明细表在自有 PG 中由主泵单线程独占写入。
|
||||||
### 2.2 消息、身份与决策
|
### 2.2 消息、身份与决策
|
||||||
|
|
||||||
`XmlCodec` 将 XML 解码为 `DecodedMessage`,包含 `SNDR / TYPE / STYP / SEQN / DTTM` 元数据和业务载荷。`MsgKind` 区分 `SCHD` 与 `FLOP` 子类型;Handler 查找与日志类型标识使用同一套映射。
|
`XmlCodec` 将 XML 解码为 `DecodedMessage`,包含 `SNDR / TYPE / STYP / SEQN / DTTM` 元数据和业务载荷。`MsgKind` 区分 `SCHD` 与 `FLOP` 子类型;Handler 查找与日志类型标识使用同一套映射。
|
||||||
@@ -117,14 +115,14 @@ Handler 不写 Kafka 或数据库。主泵负责应用决策;各类变更在
|
|||||||
|
|
||||||
### 4.1 快照发布
|
### 4.1 快照发布
|
||||||
|
|
||||||
`SCHD-RESP` 和 `SCHD-DNLD` 都进入 `SnapshotFlow`:
|
`SCHD-RESP` 和 `SCHD-DNLD` 都进入 `ScheduleProcessor`:
|
||||||
|
|
||||||
1. **暂存校验**:流式解析后完成整包校验和航班规范化;失败前不修改权威状态。暂存数据可在崩溃后从原文重建。
|
1. **暂存校验**:流式解析后完成整包校验和航班规范化;失败前不修改权威状态。暂存数据可在崩溃后从原文重建。
|
||||||
2. **应答守卫**:`RESP` 必须匹配开放的 `RQFD` 请求;无匹配、已过期或报文时间早于发送时间时,转 `SKIPPED` 并审计,不更新快照。
|
2. **应答守卫**:`RESP` 必须匹配开放的 `RQFD` 请求;无匹配、已过期或报文时间早于发送时间时,转 `SKIPPED` 并审计,不更新快照。
|
||||||
3. **SQL 原子替换**:在自有 PG 单事务内批处理写入新代 `FLIGHT_SCHD` 全量、按 `FDAY` 域内差删旧代航班,并通过 SQL CAS 推进 `SCHD_GEN` 版本。删除集为“旧代航班集合 − 新代航班集合”,仅作用于属于该代的记录,ADFT(FDAY=NULL)与已迁移航班天然存活。
|
3. **SQL 原子写入**:在自有 PG 单事务内写入校验通过的 `FLIGHT_SCHD` 航班状态及资源明细;报文未携带的航班不因本次日计划报文被删除。
|
||||||
4. **提交结果**:在同一 PG 事务中保存 `MSG_EVENT`、将消息置为 `SUCCEEDED`,并将匹配 `RESP` 的请求置为 `DONE`;事务提交后执行信箱回填。
|
4. **提交结果**:在同一 PG 事务中保存 `MSG_EVENT`、将消息置为 `SUCCEEDED`,并将匹配 `RESP` 的请求置为 `DONE`;事务提交后执行信箱回填。
|
||||||
|
|
||||||
单事务保证未提交变更整体回滚。最近一次快照重放按 `LAST_MESSAGE_ID` 识别,版本号不能单独证明消息身份;任意历史快照的重放保护仍需验收。
|
单事务保证未提交变更整体回滚。消息重放由 `PROC_STATE` 的消息 ID 与业务身份控制;版本号不能单独证明消息身份。
|
||||||
|
|
||||||
### 4.2 上游请求与静态数据
|
### 4.2 上游请求与静态数据
|
||||||
|
|
||||||
@@ -204,7 +202,7 @@ REGISTERED → SENT → WAITING → DONE
|
|||||||
| 请求超时、无匹配 RESP、时间单位不一致 | 不误用迟到应答,不提前完成请求。 |
|
| 请求超时、无匹配 RESP、时间单位不一致 | 不误用迟到应答,不提前完成请求。 |
|
||||||
| stub 误配置、重复实例、停机中断 | 生产拒绝不安全启动,工作线程能正确退出。 |
|
| stub 误配置、重复实例、停机中断 | 生产拒绝不安全启动,工作线程能正确退出。 |
|
||||||
|
|
||||||
真实适配器还需 PG 事务与补偿集成测试、快照 SQL CAS 崩溃恢复测试、Kafka 故障投递验证;常规验证命令为 JDK 25 下执行 `./gradlew test`。
|
真实适配器还需 PG 事务与补偿集成测试、日计划崩溃恢复测试、Kafka 故障投递验证;常规验证命令为 JDK 25 下执行 `./gradlew test`。
|
||||||
|
|
||||||
## 9. 实现入口
|
## 9. 实现入口
|
||||||
|
|
||||||
@@ -214,7 +212,7 @@ REGISTERED → SENT → WAITING → DONE
|
|||||||
|---|---|
|
|---|---|
|
||||||
| 收报与兼容接口 | `ingress/InboxPoller.kt`、`InboxService.kt`、`InboxController.kt` |
|
| 收报与兼容接口 | `ingress/InboxPoller.kt`、`InboxService.kt`、`InboxController.kt` |
|
||||||
| 调度与处理 | `processing/Pump.kt`(含 `MessageProcessor`)、`Handler.kt`、`Identity.kt` |
|
| 调度与处理 | `processing/Pump.kt`(含 `MessageProcessor`)、`Handler.kt`、`Identity.kt` |
|
||||||
| 快照与请求 | `processing/SnapshotFlow.kt`、`reference/RequestCoordinator.kt` |
|
| 日计划与请求 | `processing/ScheduleProcessor.kt`、`reference/RequestCoordinator.kt` |
|
||||||
| 投递与作业 | `delivery/Dispatcher.kt`、`SchdAggregation.kt`、`jobs/JobExecutor.kt` |
|
| 投递与作业 | `delivery/Dispatcher.kt`、`SchdAggregation.kt`、`jobs/JobExecutor.kt` |
|
||||||
| 持久化与恢复 | `infra/persistence/`、`infra/retry/`、`jobs/BackfillSweepJob.kt` |
|
| 持久化与恢复 | `infra/persistence/`、`infra/retry/`、`jobs/BackfillSweepJob.kt` |
|
||||||
| 启停与配置 | `PipelineLifecycle.kt`、`config/PipelineProps.kt` |
|
| 启停与配置 | `PipelineLifecycle.kt`、`config/PipelineProps.kt` |
|
||||||
|
|||||||
+69
-257
@@ -1,299 +1,111 @@
|
|||||||
# 航班运行数据接入与当前状态管理设计
|
# 运营航班状态设计
|
||||||
|
|
||||||
本模块从共享 MySQL 信箱接收 AODB 报文,在本地库维护航班当前态,再通过 Kafka 发布变化。
|
本文是航班状态的唯一现行设计规范。它定义权威数据、处理语义、生命周期和对外投递;其他文档只描述管道或产品验收,不重复定义航班状态规则。
|
||||||
|
|
||||||
未标注内容即规范要求;开放与待定项汇总在 §10。
|
|
||||||
|
|
||||||
## 1. 目标与边界
|
## 1. 目标与边界
|
||||||
|
|
||||||
1. **当前态唯一**:AODB 是业务事实来源,本地库是本模块唯一查询源。
|
系统从共享 MySQL 信箱接收 SIS/AODB 报文,把结果合并到自有 PostgreSQL 中的航班当前态,再通过 outbox 投递 Kafka。共享信箱和 Kafka 都不是状态权威,也不参与本地事务的分布式提交。
|
||||||
2. **严格有序**:单活动主泵按信箱 FIFO 处理消息。
|
|
||||||
3. **原子提交**:航班状态、处理结果、待发事件在同一事务提交。
|
|
||||||
4. **可恢复**:信箱回填与 Kafka 投递可独立重试,不重算业务。
|
|
||||||
5. **完整保存**:变长资源用明细表,不用固定槽位截断。
|
|
||||||
|
|
||||||
边界:只同步报文、维护当前态,不推导取消、延误、备降等业务状态。`PIPELINE_LOCK` 只串行化数据库事务,不能代替消息认领、选主与故障切换。
|
- `FLID` 是航班实例的唯一标识;不得由航班号、日期或资源号推断身份。
|
||||||
|
- `FLIGHT_SCHD` 及其明细表是唯一权威当前态;展示视图只读,不能作为写入或对账来源。
|
||||||
|
- 单活动主泵按信箱 FIFO 推进。事务内 `PIPELINE_LOCK` 只串行化本地状态提交,不替代选主或消息认领。
|
||||||
|
- 状态写入、outbox 事件、处理终态和回填待办在同一 PostgreSQL 事务中提交;回填与 Kafka 投递在提交后独立重试。
|
||||||
|
|
||||||
## 2. 数据来源与语义
|
现场目标库为 Oracle 11g;当前已验证的实现基准是 PostgreSQL。Oracle 适配未完成前,不能把它视为可切换的运行时选项。
|
||||||
|
|
||||||
| 来源 | 作用 |
|
## 2. 权威模型
|
||||||
|
|
||||||
|
| 对象 | 职责 |
|
||||||
|---|---|
|
|---|---|
|
||||||
| SCHD `DNLD`/`RESP` | 按 `FLID` upsert 完整航班基准状态,字段完整替换(§5);不做名单比对或差删 |
|
| `FLIGHT_SCHD` | 一行一个 `FLID`,保存标量字段、`STATE`、`STATE_VERSION`、`OPERATION_DAY`、最近消息 ID 和审计时间。 |
|
||||||
| SCHD ADFT | 新增或更新单个临时航班(§2.1) |
|
| 8 张资源明细表 | 登机门、值机柜台、转盘、计划机位、滑槽、延误、靠撤桥、轮挡等变长集合;主键为 `(FLID, ORDINAL)`。 |
|
||||||
| FLOP | 更新单个航班运行变化,增量合并,不改运营日 |
|
| `FLIGHT_ROUTE_POINT` | ROUT 与 ERUT 两类路线点,使用 `ROUTE_KIND` 区分;主键应包含该列,避免两类路线的序号冲突。 |
|
||||||
| FDEL | 终止航班实例,标记删除(§6.2) |
|
| `PROC_STATE` | 信箱消息的处理终态和业务身份幂等记录。 |
|
||||||
| 历史任务 | 归档已结束航班并物理清除(§8) |
|
| `MSG_EVENT` | 事务 outbox,承载整态投影、变更通知和删除 tombstone。 |
|
||||||
|
| `BACKFILL_TODO` | 共享信箱回填的可重试待办。 |
|
||||||
|
| `SCHD_SNAP_LOG` | 日计划处理留痕,只追加、可重建,不参与状态决策。 |
|
||||||
|
|
||||||
字段缺失两种含义:
|
### 2.1 航班身份与运营日
|
||||||
|
|
||||||
- 完整快照:未出现 = AODB 已无该数据,**清除本地旧值**。
|
`FLID` 是主键。`OPERATION_DAY` 从 SCHD 记录的 `SODT` 按配置的机场时区和切日规则推导;它不是消息接收日或落库日。
|
||||||
- 增量(FLOP):未出现 = 本次没改,**保留本地值**。
|
|
||||||
|
|
||||||
### 2.1 ADFT 语义待确认
|
一旦已写入非空 `OPERATION_DAY`,同一 `FLID` 不得改到另一个运营日。遇到冲突,整包日计划按协议错误拒绝,既有状态保持不变。尚未由日计划收录的航班可以为 `NULL`;这不表示该航班没有运行日,只表示当前模型无法为它确定归属日。
|
||||||
|
|
||||||
ADFT 的字段缺失语义尚需按 SIS 条款及真实报文确认,**确认前不得直接沿用 FLOP 的增量合并规则**。若 ADFT 含足以确定运营日的 `SODT`,应据此设置 `OPERATION_DAY`,不得默认留 `NULL`。
|
### 2.2 字段与集合
|
||||||
|
|
||||||
## 3. 数据模型
|
标量、异常对象前缀字段和 `SRVT`/`VIPF`/`MAFL` 文本字段存于主表。变长资源完整保存到明细表,保留输入顺序和协议源序号:
|
||||||
|
|
||||||
### 3.1 航班实例身份
|
- `ORDINAL` 是持久化顺序,从 1 开始;`SOURCE_SEQ` 是上游序号,允许为空或重复。
|
||||||
|
- 相同资源号不代表同一条分配,禁止按资源号去重。
|
||||||
|
- 每次持久化完整航班状态时,明细表按该 `FLID` 先删后插,以完整合并结果为准。
|
||||||
|
- ROUT 与 ERUT 是两类独立集合,不能因相同序号覆盖彼此。
|
||||||
|
|
||||||
- **`FLID`**:AODB 分配的实例 ID(`Number(1-12)`,SIS §3.16.2),全部表的唯一关联键。
|
## 3. 合并与写入语义
|
||||||
- **`FLNO`**:展示用航班号,可重复,不参与身份判定。
|
|
||||||
- **`OPERATION_DAY`**:所属运营日,一经确定不可变(§3.5、§5.3)。
|
|
||||||
- **`STATE`**:`ACTIVE` / `DELETED`。所有删除先标记;物理清除只发生在历史归档成功之后,归档结果记录在历史存储,不在当前态保留 `ARCHIVED` 状态。
|
|
||||||
|
|
||||||
同一航班号不同运营日 = 不同 `FLID`。
|
处理器保持纯粹:它根据当前完整态和已解码报文得到下一完整态与待发事件,持久化由统一事务入口执行。
|
||||||
|
|
||||||
身份属性变更由 AODB 通过 FDEL 后续接 ADFT 表达。**两条消息的 `FLID` 可能相同,也可能不同**,本模块不得预设一定产生新 `FLID`:
|
### 3.1 SCHD 日计划
|
||||||
|
|
||||||
- `FLID` 相同:按同一标识下的生命周期重激活处理(FDEL 置 `DELETED`,ADFT 恢复 `ACTIVE`);
|
SCHD DNLD/RESP 在整包校验通过后,逐条将报文携带的航班写入当前态。日计划只更新或创建其携带的 `FLID`,**不会因其他航班未出现在本次报文中而删除任何记录**。
|
||||||
- `FLID` 不同:按旧实例终止、新实例建立处理。
|
|
||||||
|
|
||||||
本模块不得合并实例,也不得由航班号或日期推断两个 `FLID` 是同一实例。
|
日计划在重叠字段上可以覆盖当前动态值;未携带的字段按合并规则保留,显式清空才清除。每个成功写入的航班推进 `STATE_VERSION`,并在同一事务登记 `KAFKA_SCHD` 与 `KAFKA_MSG` 事件。
|
||||||
|
|
||||||
### 3.2 表职责
|
消息重放由 `PROC_STATE` 的消息 ID 与 `identity_key` 控制;已成功提交的消息不得再次写入或重复登记事件。整包校验失败或运营日冲突时,整包不落地。
|
||||||
|
|
||||||
| 表 | 粒度 | 职责 |
|
DNLD、RESP 和 ADFT 均已有路由入口。RESP 的请求匹配闭环、出站请求与超时重发仍是待交付项;未注册处理器不能被视为已实现。
|
||||||
|---|---|---|
|
|
||||||
| `FLIGHT_SCHD` | 每 `FLID` 一行 | 标量当前态、`OPERATION_DAY`、`STATE`、`STATE_VERSION`、最近消息 ID |
|
|
||||||
| 8 张资源明细表 | 每 `FLID` 多行 | 登机门、值机柜台、行李转盘、计划机位、滑槽、延误、靠撤桥、轮挡 |
|
|
||||||
| `FLIGHT_ROUTE_POINT` | 每 `FLID` 多行 | ROUT/ERUT 路线点,`ROUTE_KIND` 区分 |
|
|
||||||
| `PIPELINE_LOCK` | 单行 | 串行化状态写事务 |
|
|
||||||
| `PROC_STATE` | 每消息一行 | 处理状态与重试结果;兼作快照重放判定(§5.1) |
|
|
||||||
| `MSG_EVENT`(outbox) | 每事件一行 | 状态、变更、删除通知 |
|
|
||||||
| `REQ_TRACK` / `COUTMSGS` | 每请求一行 | 请求状态与出站 |
|
|
||||||
| `BACKFILL_TODO` | 每待补偿一行 | 共享信箱回填任务 |
|
|
||||||
| `SCHD_SNAP_LOG` | 每快照一行 | 只追加留痕,不参与决策(§5.5) |
|
|
||||||
|
|
||||||
明细表共 9 张、承载 10 类集合(ROUT 与 ERUT 共用路线表);`ORDINAL` 保留输入顺序,`SOURCE_SEQ` 只存上游序号。
|
### 3.2 动态运行事件
|
||||||
|
|
||||||
分层:**决策层**(`FLIGHT_SCHD` 与各运行表)承担正确性;**留痕层**(`SCHD_SNAP_LOG`)只追加、可重建;**证据层**(报文归档)冷路径、仅用于重演审计,**尚未交付**。
|
FLOP 事件只修改它表达的字段或资源集合,其余航班状态保持不变。每个动态子类型的语义都必须有明确 Handler 规则和回归测试,不能只因已被路由就推定其业务语义完整。
|
||||||
|
|
||||||
### 3.3 完整当前态
|
动态事件保留既有 `OPERATION_DAY`,也不基于接收时间重新推导它。未知或已删除航班的具体处理遵从对应 Handler 的幂等规则。
|
||||||
|
|
||||||
主行 + 全部明细 = 完整当前态。写入前在内存生成完整新状态再落库,明细集合按组先删后插。展示视图是投影,不是权威。
|
### 3.3 删除与重建
|
||||||
|
|
||||||
### 3.4 代码共享与过站
|
FDEL 是业务删除入口:仅在 `ACTIVE → DELETED` 时推进版本、保留明细并与 tombstone 同事务登记;重复 FDEL 或不存在的航班按幂等成功处理。
|
||||||
|
|
||||||
- 主航班与共享航班是独立实例,各有 `FLID`;共享航班用 `CSOP`/`CSFT` 指向主航班,`MAFL` 存共享列表。
|
物理删除仅由独立历史清理在归档成功后执行。日计划报文不是删除依据。若未经 FDEL 而由生命周期清理,清理前需要登记一次 tombstone;已经 FDEL 的记录不重复发出。
|
||||||
- `TAOP`/`TAFL`/`TAID` 是过站关联,不是代码共享。
|
|
||||||
- 删除时共享航班 FDEL 先于主航班;按 `FLID` 各自处理,不做级联推断。
|
|
||||||
|
|
||||||
### 3.5 运营日
|
ADFT 的字段缺失语义尚待上游确认。在确认前采用保守的 Set-only 规则:出现字段可更新,缺失字段不清空;不得把它当成日计划或动态全量替换。新建 ADFT 若带可解析的 `SODT`,按同一运营日规则计算 `OPERATION_DAY`;否则保留为 `NULL`。
|
||||||
|
|
||||||
`OPERATION_DAY` 是运行保障日期,不是接收日或落库日。
|
## 4. 处理事务与失败规则
|
||||||
|
|
||||||
**计算规则**:按机场运营日规则,由计划运行时间字段(`SODT`)与机场时区(Asia/Shanghai)计算;切日边界由业务配置,不得假设等于接收日期或自然日零点。单日请求范围到运营日的映射、多日窗口中每条记录的归日,均按此规则执行。
|
所有状态处理遵循下列顺序:
|
||||||
|
|
||||||
快照取覆盖日;FLOP 保留当前值;ADFT 或先于快照的 FLOP 暂为 `NULL`,被快照收录时补齐(ADFT 含 `SODT` 时直接计算,见 §2.1)。
|
1. 主泵只处理 FIFO 队头,解码并绑定业务身份。
|
||||||
|
2. 校验消息结构、声明数量、航班标识和运营日;协议错误标记 `DEAD`,不提交半包。
|
||||||
|
3. 在一个事务中取得 `PIPELINE_LOCK`,读取当前完整态,计算下一状态,写主表和明细表,登记 outbox 和回填待办。
|
||||||
|
4. 同一事务提交处理终态;任一步失败则整体回滚并按错误类别重试或终止。
|
||||||
|
5. 提交后回填共享信箱并异步投递 outbox;后续失败不得把已提交的 `SUCCEEDED` 改回失败。
|
||||||
|
|
||||||
延误跨日仍是同一 `FLID`、运营日不变——SIS §3.16 注释 1 明确日计划不含前日延误航班,保留与清理由本模块负责。
|
`identity_key` 由 `发送方|类型|子类型|序号` 构成,用于业务重复检测。`STATE_VERSION` 是单航班的单调版本,供下游判定新旧;它不是日计划版本,也不表示运营日版本。
|
||||||
|
|
||||||
## 4. 更新模型
|
## 5. Kafka 与读取
|
||||||
|
|
||||||
以 `FLID` 为唯一边界:
|
`KAFKA_SCHD` 是按 `FLID` 的完整状态投影。Dispatcher 可以合并同一 `FLID` 尚未投递的中间版本,只发最新状态;消费端用 `(FLID, STATE_VERSION, UPDATED_AT)` 防止旧投影覆盖新状态。
|
||||||
|
|
||||||
```text
|
`KAFKA_MSG` 只通知变化,不承载权威状态;两个 topic 不承诺顺序。FDEL 和必要的生命周期清理使用 tombstone:键为 `FLID`,删除记录以 null 值投递,通知下游移除旧状态。
|
||||||
SCHD → 完整基准(字段替换,upsert;不改变 DELETED 状态)
|
|
||||||
FLOP/ADFT → 增量合并
|
|
||||||
FDEL → 标记删除(DELETED)
|
|
||||||
ADFT → 生命周期重激活(同 FLID)或新实例建立(不同 FLID)
|
|
||||||
历史任务 → 归档后物理清除(内部清理,不发业务删除事件)
|
|
||||||
```
|
|
||||||
|
|
||||||
- 每次成功写入推进 `STATE_VERSION`;状态、事件、处理终态同事务提交。
|
读取完整航班需要读取主表和全部明细。当前逐航班读取有多次查询,尚未保证跨表一致性快照;批量加载与明确的一致性读边界是后续优化项。
|
||||||
- 主链路无集合删除;删除入口只有 FDEL 与历史归档,均先标记后清除。
|
|
||||||
- **普通 SCHD 不承担恢复语义**:`DELETED` 航班被快照收录时保持 `DELETED` 并记录冲突告警(§5.1);恢复入口只有 ADFT(§6.3)。
|
|
||||||
|
|
||||||
## 5. SCHD 处理
|
## 6. 生命周期与开放项
|
||||||
|
|
||||||
设消息 `M`,记录集 `R`。身份前提:同一 `FLID` 属于唯一运营日;`FLID` 不跨日迁移。
|
运营日过去不等于航班结束。历史清理须同时满足配置保留期与终态证据或足够静默期,先成功写入历史存储,后物理删除当前态;历史存储失败时必须删除零行。
|
||||||
|
|
||||||
主链路入口为 `applyScheduleRecords`,对单日快照与滚动窗口统一适用;对单日快照不做任何名单层面的处理。
|
以下事项仍需确认或交付:
|
||||||
|
|
||||||
### 5.1 applyScheduleRecords(同一事务)
|
- Oracle 11g 的完整方言与集成验证;
|
||||||
|
- RESP 请求—应答匹配和出站请求重发;
|
||||||
|
- ADFT 缺失字段和 `FLID` 重用的上游语义;
|
||||||
|
- 未归属 `OPERATION_DAY` 航班的终止与保留策略;
|
||||||
|
- ROUT/ERUT 联合主键迁移;
|
||||||
|
- 批量一致性读取,以及动态事件仅在事务内计算一次的收敛。
|
||||||
|
|
||||||
1. 锁定 `PIPELINE_LOCK`。
|
## 7. 不变量
|
||||||
2. `M` 在 `PROC_STATE` 已有成功终态 → 重放,直接记幂等成功。
|
|
||||||
3. 校验报文完整性(§5.2),任一失败整包不落地。
|
|
||||||
4. 对每条记录按 §3.5 确定其 `OPERATION_DAY`。
|
|
||||||
5. 校验每个 `FLID` 的既有 `OPERATION_DAY`(§5.3)。
|
|
||||||
6. 按完整快照语义 upsert 每个航班(§5.4);**`DELETED` 航班保持 `DELETED`,记录冲突告警 `SCHD_REVIVE_CONFLICT`,不恢复 `ACTIVE`**。
|
|
||||||
7. 逐航班推进 `STATE_VERSION`,登记状态事件与处理终态。
|
|
||||||
|
|
||||||
任一步失败整体回滚。
|
- 本地 PostgreSQL 当前态是唯一权威;信箱、Kafka、Redis 和展示视图不是权威。
|
||||||
|
- 同一时刻只有一个主泵推进 FIFO 状态;状态、事件、终态和回填意图原子提交。
|
||||||
### 5.2 报文完整性
|
- `FLID` 唯一,已确定的 `OPERATION_DAY` 不可改变。
|
||||||
|
- 报文未携带的字段不会被隐式清空;集合按完整合并结果写入。
|
||||||
五项校验:`RECS` 0–9999 且等于实收 `FLTR` 数;每条记录含合法数字型 `FLID`;快照内不重复;每条记录的运营日可计算且在报文覆盖范围内。
|
- 缺席于某个日计划不构成删除理由;删除只由 FDEL 或受控历史清理触发。
|
||||||
|
- 外部副作用失败可重试,不回滚已提交的本地业务结果。
|
||||||
**记录完整与成员完整必须分开**:
|
|
||||||
|
|
||||||
- **记录完整**:某 `FLID` 的字段是该航班的完整状态 → 允许覆盖字段。48 小时滚动窗口满足此维度。
|
|
||||||
- **成员完整**:报文含某运营日全部 `FLID`。主链路不使用成员完整性;若将来引入名单对账,需另行设计并单独定案。
|
|
||||||
|
|
||||||
### 5.3 航班归属
|
|
||||||
|
|
||||||
| 主行情况 | 处理 |
|
|
||||||
|---|---|
|
|
||||||
| 不存在 | 创建,`OPERATION_DAY` 按记录计算,`STATE = ACTIVE` |
|
|
||||||
| `NULL` | 首次确定 |
|
|
||||||
| 与记录计算值相同 | 按快照更新状态 |
|
|
||||||
| 与记录计算值不同 | 违反身份约束:不改写、整包拒绝 `DEAD(PROTOCOL)`、告警 `SAME_FLID_ACROSS_OPERATION_DAYS` |
|
|
||||||
|
|
||||||
第四行意味着串日、错发或数据污染:不静默保留,不迁移归属,整包拒绝后交人工确认。
|
|
||||||
|
|
||||||
### 5.4 字段语义
|
|
||||||
|
|
||||||
| 输入 | 字段缺失含义 |
|
|
||||||
|---|---|
|
|
||||||
| `DNLD`/`RESP` | AODB 已无该数据 → 清除本地旧值 |
|
|
||||||
| `FLOP` | 本次没改 → 保留本地值 |
|
|
||||||
| `KAFKA_SCHD` | 当前态没有该字段 → 消费者删除旧值 |
|
|
||||||
|
|
||||||
标量出现 Set、缺失 Clear;集合出现 Replace、缺失 Replace 空集。清除只覆盖正式映射的字段。
|
|
||||||
|
|
||||||
### 5.5 时序约束与留痕
|
|
||||||
|
|
||||||
**快照与 FLOP 的覆盖顺序是核心时序问题。** `SEQN` 重启后不可比、不表达业务新旧,因此**不启用陈旧拦截**,只承诺**按信箱接收顺序形成当前态**。“快照比 FLOP 权威”不成立,不得对外承诺。较旧的 SCHD 晚于 FLOP 到达可能把新动态改回旧值——接收序模型的已知代价,靠上游顺序保证或下一次 FLOP 纠正。`SEQN` 仅用于同会话顺序观测(下降记 `SEQN_REGRESSION` 并告警)。
|
|
||||||
|
|
||||||
事务外追加一条 `SCHD_SNAP_LOG`:
|
|
||||||
|
|
||||||
| 字段 | 说明 |
|
|
||||||
|---|---|
|
|
||||||
| `MSG_ID` / `RECV_AT` | 消息 ID、接收时刻(UTC) |
|
|
||||||
| `SCOPE_START` / `SCOPE_END` | 报文覆盖的运营日范围(单日时两者相等) |
|
|
||||||
| `RECS` / `UPSERTED` / `DURATION_MS` | 规模、写入数、耗时 |
|
|
||||||
| `RESULT` | `COMMITTED` / `REPLAY_SKIPPED` / `ROLLED_BACK` |
|
|
||||||
| `FLAGS` | `EMPTY` / `RECS_DROP` / `SEQN_REGRESSION` / `DAY_MISMATCH` / `SCHD_REVIVE_CONFLICT` |
|
|
||||||
| `ARCHIVE_KEY` | 原文归档引用 |
|
|
||||||
|
|
||||||
规则:`RESULT` 与 `FLAGS` 分列(可“成功且告警”);一行 = 一次尝试,重放也记;留痕不参与决策,写失败只记指标;保留 90 天,按 `(SCOPE_END, RECV_AT)` 清理。
|
|
||||||
|
|
||||||
## 6. 动态事件与删除
|
|
||||||
|
|
||||||
### 6.1 FLOP
|
|
||||||
|
|
||||||
读取完整当前态 → 合并变化 → 保留运营日 → `STATE_VERSION` 加一 → 同事务登记 `KAFKA_MSG`、`KAFKA_SCHD` 与处理结果。
|
|
||||||
|
|
||||||
### 6.2 FDEL
|
|
||||||
|
|
||||||
同一事务内:
|
|
||||||
|
|
||||||
1. 按 `FLID` 定位。
|
|
||||||
2. `STATE = ACTIVE`:置 `DELETED`,推进 `STATE_VERSION`,明细保留,发布删除事件。
|
|
||||||
3. `STATE = DELETED`:记幂等成功,**不推进 `STATE_VERSION`,不重复发布删除事件**。
|
|
||||||
4. 不存在:记幂等成功(迟到、重复不报错)。
|
|
||||||
|
|
||||||
**删除一律标记,不物理清除**:`FLID` 复用未确认(§10)、删除与更新事件可能乱序(§7.3),物理清除统一由历史归档执行(§8.2)。共享航班 FDEL 先于主航班,各自处理,不做级联推断。
|
|
||||||
|
|
||||||
### 6.3 ADFT 恢复
|
|
||||||
|
|
||||||
ADFT 到达且 `FLID` 已存在、`STATE = DELETED`:这是同 `FLID` 生命周期重激活(§3.1),恢复 `ACTIVE`,推进 `STATE_VERSION`,登记状态事件。`FLID` 不存在则按新实例建立。
|
|
||||||
|
|
||||||
## 7. 对外处理
|
|
||||||
|
|
||||||
### 7.1 请求
|
|
||||||
|
|
||||||
经 `REQ_TRACK` 登记、`COUTMSGS` 发出;同类请求只留一条有效,新请求置旧为 `EXPIRED`。**只有 `RESP` 完成 RQFD 请求**,按(运营日、发送方、请求类型)匹配最新一条 `PENDING`;`DNLD` 是主动下发,独立处理,除现场确认的扩展规则外不得用于完成请求。协议无请求关联号,匹配规则待验收。
|
|
||||||
|
|
||||||
主链路不依赖逐日请求;当前只收定时下发的 48 小时窗口即为主链路的正常输入。
|
|
||||||
|
|
||||||
### 7.2 回填
|
|
||||||
|
|
||||||
提交后回填共享信箱;回填失败不得把已提交的 `SUCCEEDED` 改回 `FAILED`。
|
|
||||||
|
|
||||||
### 7.3 Kafka
|
|
||||||
|
|
||||||
`KAFKA_SCHD` 发整态:Dispatcher 合并同一 `FLID` 未发事件,按最新 `STATE_VERSION` 输出。`KAFKA_MSG` 只通知变化。两主题间不保证顺序;整态键缺失表示删除旧值。
|
|
||||||
|
|
||||||
判旧:消费端 `(FLID, STATE_VERSION, UPDATED_AT)`。
|
|
||||||
|
|
||||||
删除用 tombstone:载荷至少含 `FLID`、`STATE_VERSION`、`DELETED`;仅在 `ACTIVE → DELETED` 时发布,与删除同事务登记,投递失败持续重试。物理清除(§8.2)是内部清理,**不再发布业务删除事件**;仅对未经 FDEL、由生命周期直接清除的航班,在清除前补发一次删除事件。即使确认 `FLID` 永不复用,`STATE_VERSION` 也不能省——更新与删除事件仍会乱序;`FLID` 复用风险与 GENERATION 方案见 §10。
|
|
||||||
|
|
||||||
### 7.4 身份不变量
|
|
||||||
|
|
||||||
- `FLID` 是主键;一个 `FLID` 最多一个非空 `OPERATION_DAY`,一经确定不可改。
|
|
||||||
- 同 `FLNO` 不同运营日 = 不同 `FLID`。
|
|
||||||
- 身份变更时 FDEL 与 ADFT 的 `FLID` 可能相同也可能不同(§3.1);不得由航班号或日期推断实例;`FLID` 不同时是终止与新建,不是主键变更。
|
|
||||||
|
|
||||||
`OPERATION_DAY` 不可变由应用层在快照入口校验;需数据库层强化可加触发器或 `WHERE operation_day IS NULL OR operation_day = :d`。
|
|
||||||
|
|
||||||
## 8. 生命周期与清理
|
|
||||||
|
|
||||||
运营日过去不等于航班结束,不能按日期删除。
|
|
||||||
|
|
||||||
### 8.1 历史判定
|
|
||||||
|
|
||||||
**单一时间窗不构成删除依据**;须同时满足“超过配置时间窗”且有终态证据或足够长的静默期:
|
|
||||||
|
|
||||||
- 已取消(`CNCL` 非空)超过 48 小时;
|
|
||||||
- 已完成离港/到港终态(`NAAT`/`NEAT`,字段含义与来源系统需在术语表确认,§10)超过 48 小时;
|
|
||||||
- `STATE = DELETED` 超过 48 小时;
|
|
||||||
- 无终态字段时,最后一次有效更新超过兜底期限(默认 7 天)。
|
|
||||||
|
|
||||||
窗口按机场时区(Asia/Shanghai)计算。
|
|
||||||
|
|
||||||
### 8.2 归档与清除(顺序不可颠倒)
|
|
||||||
|
|
||||||
1. `HISTORY_SWEEP` 选出满足 §8.1 的航班(含 `DELETED`)。
|
|
||||||
2. 写入历史存储。
|
|
||||||
3. 历史存储返回成功的 `FLID` 集合,对应行**物理删除**主行与明细;归档结果只记录在历史存储,当前态不保留归档状态。
|
|
||||||
4. 未经 FDEL 的航班在清除前补发一次删除事件(§7.3);其余不发。
|
|
||||||
5. 失败或不明确的保留重试。
|
|
||||||
|
|
||||||
历史存储未接通时必须删 0 条;绝不允许先删当前态再补历史。**物理清除只发生在本步骤**。
|
|
||||||
|
|
||||||
### 8.3 保留期
|
|
||||||
|
|
||||||
| 对象 | 默认保留 | 前置条件 |
|
|
||||||
|---|---|---|
|
|
||||||
| 留痕 `SCHD_SNAP_LOG` | 90 天 | 按 `(SCOPE_END, RECV_AT)` 清理 |
|
|
||||||
| `OPERATION_DAY = NULL` 航班 | 7 天 | 仍未被快照收录;终止规则未定前只增不删 |
|
|
||||||
|
|
||||||
## 9. 失败与读取
|
|
||||||
|
|
||||||
| 错误 | 处理 | 队头行为 |
|
|
||||||
|---|---|---|
|
|
||||||
| 非法报文、数量不符、容量超限 | `DEAD`,不重试 | 立即释放 |
|
|
||||||
| 未支持类型 | `FAILED(UNSUPPORTED)` | 达阈值转 `DEAD` |
|
|
||||||
| 数据库或内部故障 | `FAILED(INFRA)`,退避重试 | 成功或超限前阻塞 |
|
|
||||||
| 快照含归属日不符的 `FLID` | 整包拒绝 `DEAD(PROTOCOL)`,留痕告警 | 立即释放,交人工确认 |
|
|
||||||
| `SEQN` 回退 / `SCHD_REVIVE_CONFLICT` | 只记 `FLAGS` 并告警 | 不阻塞 |
|
|
||||||
| 留痕写失败 | 只记 error 指标 | 不阻塞 |
|
|
||||||
|
|
||||||
读取:完整航班状态须在一致性读事务中读主表与全部明细,且过滤 `STATE = ACTIVE`。当前逐航班读取有 N+1 问题,主表与明细可能不在同一快照——批量加载与一致性读边界待补。
|
|
||||||
|
|
||||||
## 10. 未定事项
|
|
||||||
|
|
||||||
由 ACM2-31 跟踪:快照与动态事件顺序、FLOP 集合语义、删除事件版本、幂等键生命周期、FIFO 参数、一致性读取、快照完整性校验、Oracle 适配。
|
|
||||||
|
|
||||||
| 事项 | 状态 |
|
|
||||||
|---|---|
|
|
||||||
| SCHD 按 `FLID` upsert 且不恢复 `DELETED`;删除一律标记,物理清除由历史归档执行 | 已定案(§4、§5.1、§6.2、§8.2) |
|
|
||||||
| FDEL + ADFT 的 `FLID` 可能相同或不同 | 已定案为处理规则(§3.1、§6.3);上游实际行为待 SIS 条款核对 |
|
|
||||||
| `OPERATION_DAY` 按机场运营日规则由 `SODT` 与机场时区计算,切日边界业务配置 | 已定案(§3.5);边界值待业务确认 |
|
|
||||||
| ADFT 字段缺失语义 | **待确认**(§2.1);确认前不得沿用 FLOP 合并规则 |
|
|
||||||
| `FLID` 是否会被复用 | **待上游书面确认**;确认前保持 `DELETED` 中间态。若不能保证永不复用,需引入生命周期表 `FLIGHT_ID_LIFECYCLE(FLID, GENERATION, LAST_VERSION)`,对外版本升级为 `(FLID, GENERATION, STATE_VERSION)` |
|
|
||||||
| 上游取消是否必然伴随 FDEL | **待上游确认**;确认前不做任何基于名单缺席的删除 |
|
|
||||||
| 旧快照晚于 FLOP 的覆盖风险 | 接收序模型的已知代价;上游顺序保证待确认(ACM2-31#8) |
|
|
||||||
| `NAAT` / `NEAT` 的业务含义与来源系统 | 待术语表确认(§8.1) |
|
|
||||||
| 逐运营日请求完整日计划 | 未完成;主链路不依赖,是否需要待上游 FDEL 可靠性确认后再评估 |
|
|
||||||
|
|
||||||
当前偏差:GTDT 按 Replace 处理但 FLOP 集合语义未确认;动态事件在锁外预览、事务内重算,目标只算一次;回填待办提交后写,崩溃窗口不可恢复,目标事务内预登记。
|
|
||||||
|
|
||||||
### 规则 M:快照与动态事件的应用顺序
|
|
||||||
|
|
||||||
当前实现按信箱接收顺序应用 SCHD 与 FLOP。SCHD 处理时完整替换对应字段,因此接收顺序上后到的 SCHD 会覆盖先到的 FLOP——**这只是当前实现结果,不代表 SCHD 在业务时间上优先**,不得对外承诺快照权威(ACM2-31#8)。
|
|
||||||
|
|
||||||
### 规范依据(SIS)
|
|
||||||
|
|
||||||
| 结论 | 出处 |
|
|
||||||
|---|---|
|
|
||||||
| 以 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 |
|
|
||||||
|
|||||||
@@ -1,185 +1,5 @@
|
|||||||
# 历史存档说明
|
# 历史设计存档说明
|
||||||
|
|
||||||
以下是整理前的决策原文,包含已撤销方案和当时的交付声明;现行结论见 [决策摘要](../decision-flight-state.md)。
|
旧版航班状态方案已撤销,不再作为设计或实现依据。
|
||||||
|
|
||||||
# 决策:运营航班表 FLIGHT_SCHD 落自有 PostgreSQL 作阶段 A 权威(已定案 · 采纳选项 C)
|
现行航班设计统一见 [运营航班状态设计](../flight-state.md)。
|
||||||
|
|
||||||
> **状态**:已定案(讨论 issue:**ACM2-28**,采纳选项 C;关联修订 ACM2-12)。
|
|
||||||
> 本文正式确立选项 C 为最终方案:运营航班权威 `FLIGHT_SCHD` 与代版本 `SCHD_GEN` 提前至阶段 A 落自有 PostgreSQL;Redis 彻底退出动态权威与写路径。
|
|
||||||
> 交叉引用:[architecture.md](../architecture.md)、[design.md](../design.md)、[user-stories.md](../user-stories.md)、ACM2-10(FS1–FS8 实施批次)。
|
|
||||||
|
|
||||||
> **2026-09-08 复核入口**:详细证据与重构提案见 [运营航班状态设计评审](../flight-state.md)。
|
|
||||||
> 本轮确认的部署边界:现场提供 Oracle 时使用 Oracle 11g,否则自行部署 PostgreSQL。
|
|
||||||
> 评审保留单库原子提交方向,但发现 §9 固定资源槽位与本仓库三登机门样例冲突,
|
|
||||||
> 并指出集合往返、迁移与快照 CAS 的风险。**§9 全宽表·零子表方案已按 v2 设计撤销**,
|
|
||||||
> 现行权威口径见 [§10 v2 落地](#10-acm2-29-v2-无损明细表方案落地2026-09-08)、
|
|
||||||
> 现行设计见 [flight-state.md](../flight-state.md);§1–§9 保留为历史记录。
|
|
||||||
|
|
||||||
## 1. 问题
|
|
||||||
|
|
||||||
阶段 A 航班动态权威 = Redis(`flightInfo` hash + `SCHD_GEN`),永续驻留、不落任何关系表
|
|
||||||
(ACM2-12)。FLIGHT_STATE 表原属阶段 B(`Decision.kt` 注释即「阶段 B 落 FLIGHT_STATE
|
|
||||||
同事务」)。要回答的问题:**是否把 FLIGHT_STATE 提前到阶段 A 落自有 PG,作为运营航班的
|
|
||||||
权威存储。**
|
|
||||||
|
|
||||||
## 2. 触发重估的事实
|
|
||||||
|
|
||||||
| # | 事实 | 出处 |
|
|
||||||
|---|---|---|
|
|
||||||
| F1 | Redis 全损后,FLOP 报文按 KEEP 语义「航班不存在 → SUCCEEDED 不重试」持续终结——空态被当正常态,**状态损坏持续到下一次完整 DNLD**;且这些报文已回填 `DATE_PROCESSED`,`ReplayService` 白名单(FAILED/DEAD)无法找回 | US-05 AC3、design.md §1.1 |
|
|
||||||
| F2 | 当前唯一恢复手段 = 等下一次 DNLD 或人工触发 RQFD(依赖 AODB 外部响应,超时 60s);无本地 durable 副本 | US-08、design.md §3.4 |
|
|
||||||
| F3 | dev Valkey 虽配 AOF(`compose.yaml --appendonly yes`),**生产 Redis 拓扑(持久化策略/副本)未定**;Redis 持久化本就是尽力而为,不构成状态安全边界 | compose.yaml、§8 部署姿态 |
|
|
||||||
| F4 | PG 已是处理管道硬依赖(PROC_STATE/MSG_EVENT),主泵本就停摆于 PG 不可用——航班状态放 PG **不新增** 系统级 SPOF | design.md §2 |
|
|
||||||
| F5 | U05(PG 本地事务边界)正在实装;此刻调整事务模型成本最低,切流后迁移要重开 I2/I5 与影子对拍口径 | ACM2-10 U05 |
|
|
||||||
| F6 | U09(gen Redis 内 CAS 协议重设计)存在的根因就是「权威在 Redis、终态在 PG」的跨存储窗口——ACMA-8 v4 原设计 gen 本在 DB,ACM2-12 迁 Redis 仅因 FLIGHT_STATE 缓做 | design.md §3.4 已知缺口 |
|
|
||||||
| F7 | Handler 输入视图 `hgetAllFlightInfo()` 每报文全量读 hash,已是 U22–U24 已知缺口;PG 按 FLID 索引读可顺带收敛 | design.md §9 |
|
|
||||||
|
|
||||||
## 3. 选项
|
|
||||||
|
|
||||||
### A — 维持缓做 + 运维缓解(ACM2-12 现状)
|
|
||||||
|
|
||||||
冷启动空态自动触发 RQFD、生产 Redis 强制 AOF+副本部署要求、Runbook 记录重建流程。
|
|
||||||
**局限**:F1 的永久损坏窗口依旧存在,缓解只是缩短;恢复依赖外部系统可用性。
|
|
||||||
|
|
||||||
### B — PG 镜像(write-behind 灾备副本,非权威)
|
|
||||||
|
|
||||||
主泵在 Redis 写成功后异步把变更镜像到 PG,仅供灾难重建。
|
|
||||||
**局限**:镜像滞后窗口内的 FLOP 效果同样丢失,恢复后仍需 DNLD 修正(与 A 等价的损伤面);
|
|
||||||
却要付出接近 C 的复杂度(表 + 双表示一致性哨兵 + 重建任务)。性价比最差,仅列出备选。
|
|
||||||
|
|
||||||
### C — FLIGHT_STATE 落自有 PG,作为阶段 A 权威(推荐)
|
|
||||||
|
|
||||||
航班状态变更并入既有 **PG 事务 2**(与 `MSG_EVENT` 插入、`PROC_STATE→SUCCEEDED` 同事务
|
|
||||||
原子提交);Redis 退出动态权威写路径。
|
|
||||||
|
|
||||||
- 跨存储双写窗口(I2 的 Redis 先写)整体消失;U09 从「Redis Lua 协议重设计」变为
|
|
||||||
「SQL 版本 CAS + 集成测试」,gen/SCHD_GEN 随 FLIGHT_STATE 回 PG(回到 ACMA-8 v4 形态)。
|
|
||||||
- Redis 全损场景不再存在:PG 即状态,重启即恢复;F1 的损坏路径被根除。
|
|
||||||
- Handler 输入改为按 FLID 索引读(F7);US-12 `GET /all/flights` 读 PG。
|
|
||||||
- 影子对拍沿用 ACM2-12 既有口径(自有 PG 独立 schema 比对),不新增负担。
|
|
||||||
- 阶段 B 不受影响:清场/判史改为 SQL 驱动,ES 仍是历史投影。
|
|
||||||
- 性能:机场报文量级(秒级峰值)下单行 JSONB upsert 亚毫秒,且在既有事务内,无新增往返。
|
|
||||||
|
|
||||||
**C 的代价**(须如实计入):
|
|
||||||
|
|
||||||
- 推翻 ACM2-12 阶段 A 存储口径,I2/I5 不变量重述,U29 不变量测试清单同步。
|
|
||||||
- `FlightStateRepository` 从 day 粒度(`replaceDay`)重设计为 FLID 粒度 upsert + day 快照
|
|
||||||
replace;SnapshotFlow 的 Lua 差删改 SQL;`redis-flight-store` 健康指示器调整。
|
|
||||||
- Redis 在阶段 A 角色大幅缩小(仅剩 orms_stand 热点缓存可选),部署面与文档需收口。
|
|
||||||
- 与 U05/U09/U15 排序重排:先定此决策,再收 U05 事务边界。
|
|
||||||
|
|
||||||
## 4. 对比
|
|
||||||
|
|
||||||
| 维度 | A 缓做+缓解 | B 镜像 | C PG 权威 |
|
|
||||||
|---|---|---|---|
|
|
||||||
| Redis 全损后果 | 状态永久损坏至下次 DNLD | 损坏窗口缩短,仍需 DNLD 修正 | 不存在该场景 |
|
|
||||||
| 事务模型 | 跨存储双写(I2/U09 复杂度保留) | 双写 + 镜像一致性 | 单库原子(U09 消解为 SQL) |
|
|
||||||
| 新增范围 | 无 | 表+哨兵+重建 | 表+接口+事务改造(并入 U05/U09 批次) |
|
|
||||||
| 影子对拍 | 不变 | 需比对三方 | 不变(口径已是 PG schema 比对) |
|
|
||||||
| 恢复 RTO/RPO | 依赖 AODB 响应 | 本地副本+DNLD 修正 | 重启即恢复,RPO=0 |
|
|
||||||
|
|
||||||
## 5. 建议
|
|
||||||
|
|
||||||
**推荐 C**。核心理由:F1 的损坏是**永久且不可自动找回**的(报文已回填、不可重放),
|
|
||||||
选项 A/B 只能缩短窗口不能根除;而 C 的增量成本大部分落在 U05/U09 本就要动的事务边界上,
|
|
||||||
时机(F5)与代价重合。若评审认为生产 Redis 必然配强持久化+副本且接受 DNLD 重建窗口,
|
|
||||||
A 是最小代价回退位;B 不建议。
|
|
||||||
|
|
||||||
## 6. 定案结论(ACM2-28 决策记录)
|
|
||||||
|
|
||||||
| # | 问题 | 定案结论 |
|
|
||||||
|---|---|---|
|
|
||||||
| Q1 | 生产 Redis 拓扑 / RPO | **不再阻塞**。Redis 退出权威与写路径,不构成状态安全边界。 |
|
|
||||||
| Q2 | 表形态 | 表名定案 `FLIGHT_SCHD`。FLID 主键 + FLTR JSONB 全量 + FDAY 所属代列(可空)。派生字段后置。 |
|
|
||||||
| Q3 | U09 重定义 | 「Redis Lua 协议重设计」**取消**,改为「`SCHD_GEN` SQL 版本 CAS + Testcontainers PG 集成测试」。 |
|
|
||||||
| Q4 | Redis 去留 | 阶段 A 动态写路径归零;orms_stand 缓存不保留;US-12 读 PG;`redis-flight-store` 健康指示器移除。 |
|
|
||||||
| Q5 | 不变量重述 | I2(变更+事件+SUCCEEDED 单事务提交);I4(覆盖+差删+版本推进单事务);I5(单写者主泵线程,PG advisory lock 保护)。 |
|
|
||||||
| Q6 | 影子对拍口径 | nextgen PG `FLIGHT_SCHD` vs legacy Redis `flightInfo` 跨存储 AST 递归比对(FS7 工具)。 |
|
|
||||||
|
|
||||||
## 7. 落地完成清单(FS1–FS8 全部交付)
|
|
||||||
|
|
||||||
- **FS1** 迁移 `V1.1.0__flight_schd.sql`:创建 `FLIGHT_SCHD` 与 `SCHD_GEN`(TIMESTAMPTZ 规范)。
|
|
||||||
- **FS2** `FlightSchdRepository` 接口与实装:快照批量写入、增量更新(ON CONFLICT 保留 FDAY)、域化差删、点查、`SCHD_GEN` SQL CAS、历史清场 `deleteByFlids`。
|
|
||||||
- **FS3** `MessageProcessor` 事务 2 扩展:变更写入 + 事件写入 + `SUCCEEDED` 在单 PG 事务原子提交;Handler 视图按 FLID 点查。
|
|
||||||
- **FS4** `SnapshotFlow` SQL 化:单事务内批处理 upsert + 域内差删 + SQL CAS 推进 + 事件入队 + 终态标记;`JobExecutor` 清场删除闭环。
|
|
||||||
- **FS5** Redis 退役收口:删除 `FlightRedisClient`、Lua 脚本、`FlightRedisHealthIndicator`、`REDIS_FLIGHT_INFO` 投影与相关配置。
|
|
||||||
- **FS6** U29/U09 不变量测试门禁:崩溃幂等无自增、CAS 防并发、ADFT 存活保障、UTC 方言测试、ES 历史清场 5 场景全绿。
|
|
||||||
- **FS7** 影子对拍 Diff 工具:`FlightStoreDiffTool` 递归 AST 字段归一化比较与已知合法偏离识别。
|
|
||||||
- **FS8** 文档回改:架构、设计、用户故事与项目规范同步收敛。
|
|
||||||
|
|
||||||
## 8. 修订:11g 现场约束下废除 JSON 存储(本节追加,不改写上文定案历史)
|
|
||||||
|
|
||||||
> **触发**:现场环境只提供 Oracle 11g(无任何 JSON 能力——无 `JSON_VALUE`、无 `IS JSON` 约束、无 JSON 类型,
|
|
||||||
> JSON 支持自 12.1.0.2 才引入)。Q2 定案的「FLTR JSONB 全量」存储形态在该约束下不成立:
|
|
||||||
> 整文档存储丧失库端校验、字段级索引与直接 SQL 可查性,违背「运营航班可被 DBA/运营直接使用」的初衷。
|
|
||||||
|
|
||||||
**修订结论**:
|
|
||||||
|
|
||||||
| # | 问题 | 修订结论 |
|
|
||||||
|---|---|---|
|
|
||||||
| R1 | 表形态 | 废除 `FLTR_JSON` JSONB 整文档,改为**一行一航班的宽表**:FLID 主键 + FDAY 代列 + SCHD.FLTR 标量字段列(锚定 `unisysaodbsis.xsd` 契约与 legacy 派生字段 ABDG/LPSDT/ABN)+ 1:N 明细集合序列化文本列。字段即列,天然可索引、可直查。 |
|
|
||||||
| R2 | 集合字段 | 登机口/柜台/转盘/桥/延误等 1:N 明细(单航班可达 99 条)暂存序列化文本列(`*_TXT`,11g 移植为 CLOB);阶段 2/3 Handler 钉死语义后按需升独立子表。 |
|
|
||||||
| R3 | 值语义 | 全部字段保持 legacy 字符串原样(不做库端类型转换),保证影子对拍逐字段保真;范围查询需要的类型化列(如 SODT→DATE)按查询需求逐列后置提升。 |
|
|
||||||
| R4 | SCHD_GEN | `FLIDS_JSON` 同步废除,展开为 `SCHD_GEN_FLID(FDAY, FLID)` 行;版本 CAS 语义不变。 |
|
|
||||||
| R5 | 值机视图 | Handler 在线视图契约由 `flid → FLTR_JSON` 改为 `flid → 字段集`(与 legacy `hgetAllFlightInfo` hash 同构);增量写语义=字段级合并(与 legacy hmset 一致),快照=整体替换。 |
|
|
||||||
| R6 | 对拍口径 | FS7 Diff 工具改为 PG 宽表列值 vs legacy FLTR JSON 的逐字段归一化比对(数值精度/空值等价规则保留),比原 JSONB AST 比对更精确到字段。 |
|
|
||||||
|
|
||||||
**未尽事项(11g 方言移植不在本修订范围,另行决策)**:存储模型已 11g 兼容,但仓储层仍存 PG 方言
|
|
||||||
(`ON CONFLICT` upsert 需改 `MERGE`)、I5 advisory lock 的 11g 替代(`DBMS_LOCK`)、Flyway/驱动
|
|
||||||
对 11.2 的支持矩阵。若「自有 PG → 现场 11g」成为确定部署形态,需按 ACM2-28 体例开独立决策记录
|
|
||||||
重开「自有库」平台定案,评估点在方言与并发原语,不在本修订已解决的存储形态。
|
|
||||||
|
|
||||||
## 9. ACM2-29 修正落盘:全宽表·零子表(Zero-Subtable Wide Table)
|
|
||||||
|
|
||||||
R2 的「`*_TXT` 过渡 + 按需升独立子表」经 `docs/legacy/SIS_AODB_RMS-V0.1.md` 报文样例核验与
|
|
||||||
成都现场(双流/天府)地服实际规律复核,确认为对 XSD 理论上限(maxOccurs="99")的过度设计,
|
|
||||||
正式废除。16 个明细集合全部收敛为 `FLIGHT_SCHD` 宽表的标准 VARCHAR 标量列或紧凑格式化字串,
|
|
||||||
零子表、零 CLOB(V1.2.0 迁移落地):
|
|
||||||
|
|
||||||
- **平铺标量列**(槽位号即报文序号属性,可按需直接追加普通 B-tree):登机门 `GATE1/2+PGOT/PGCT/GOTM/GCTM/GTYP`
|
|
||||||
×2 组;值机柜台 `CHKC1..3` 全属性(同柜台分舱复用条目写侧抹平去重);转盘 `BELT1/2` 全属性
|
|
||||||
(计划时刻 `BPCOT/BPCCT` 专属前缀避免与值机同名);计划机位 `PSST1/2`;离港通道 `CHUT1/2`
|
|
||||||
(等级/类型 `CHCLS/CHTYP` 专属前缀)。槽位数按现场规律定界(2/3/2/2/2),超界条目按定案丢弃。
|
|
||||||
- **单值/里程碑标量列**:延误 `DELY_CODE/DELY_STRT/DELY_DURA/DELY_REMC`(业务上任意时刻仅 1 个
|
|
||||||
有效延误,覆盖语义);靠撤桥 `ABTM_A/ABTM_D`(桥号沿用派生列 ABDG);轮挡 `CHOT_ON/CHOT_OFF`
|
|
||||||
(机位沿用派生列 STND);异常 `FDIV/FRET/FLAB` 前缀标量列(规范 1:0..1 单值异常)。
|
|
||||||
- **紧凑 VARCHAR 字串列**(无界/航路型集合,11g VARCHAR2 内联存储,非 CLOB):
|
|
||||||
`ROUT_PATH/ERUT_PATH`(≤7 站紧凑航路 `"APCD/SCAT/SCDT,..."`);`SRVT_TEXT/VIPF_TEXT/MAFL_TEXT`
|
|
||||||
(服务/VIP/共享列表条数无 XSD 上限,存 JSON 数组;超长由列约束 fail fast,不静默截断)。
|
|
||||||
- **消息语义**:运营资源 = 单资源集合级全量快照替换(集合键出现即整集合覆盖,缺槽位置 NULL,
|
|
||||||
序号属性 "0" 为显式删除标记);外层航班字段仍为字段级增量合并(仅新增/覆盖)。
|
|
||||||
- **读侧视图**:由平铺列重建 16 个集合键,与 legacy `flightInfo` hash 同构——KAFKA_SCHD 线格式
|
|
||||||
(FLTR JSON 数组)与 FS7 Diff 逐字段比对均依赖该同构视图,存储形态变化不出仓储边界。
|
|
||||||
已知保真边界:`ABTM/CHOT` 只保留里程碑时刻(资源号沿用 ABDG/STND 派生列);航路空串属性
|
|
||||||
与缺失属性在紧凑字串中合并为空槽位;`FDIV/FRET/FLAB` 自由文本键名待阶段 2 Handler 钉死。
|
|
||||||
- **出站序列化**:`FlightFieldsJson` 对契约结构字段解析 JSON tree 输出原生数组/对象,
|
|
||||||
杜绝集合被再次编码成字符串的双重转义。
|
|
||||||
- **I5 单写者锁修正**:不再依赖 PG advisory lock/11g `DBMS_LOCK`。V1.2.0 创建 `PIPELINE_LOCK`
|
|
||||||
单行锁表,处理事务对 `FLIGHT_SCHD_WRITER` 行执行 `SELECT ... FOR UPDATE`;连接断开、提交或
|
|
||||||
回滚时由数据库释放,PG 与 11g 同构,无 DBA 特权依赖。
|
|
||||||
|
|
||||||
16 个 `*_TXT` 文本列由 V1.2.0 全部删除;运营查询索引(如 `GATE1/CHKC1/DELY_CODE`)按需以普通
|
|
||||||
B-tree 逐列追加,11g/PG 零方言成本。
|
|
||||||
|
|
||||||
Oracle 11g 的 `MERGE INTO` 方言、Flyway 11.2 支持版本和 ojdbc 认证组合仍必须在目标数据库环境
|
|
||||||
中完成平台决策与集成验收;不能用 PostgreSQL 测试结果替代该外部环境证据。
|
|
||||||
|
|
||||||
## 10. ACM2-29 v2 无损明细表方案落地(2026-09-08)
|
|
||||||
|
|
||||||
按 [评审报告](../flight-state.md)(F1–F9)与
|
|
||||||
[flight-state.md](../flight-state.md) 评审定案,撤销 §9「全宽表·零子表」
|
|
||||||
作为权威存储形态,落地无损模型;本节为当前有效规则索引:
|
|
||||||
|
|
||||||
- **存储**:`FLIGHT_SCHD` 保留标量/异常前缀/无界文本列(V1.4.0 已 DROP 槽位、里程碑与紧凑
|
|
||||||
航路列及冗余索引);10 类重复集合由 9 张明细表 + `flight_route_point(ROUTE_KIND)` 承载,
|
|
||||||
PK `(FLID, ORDINAL)`,`SOURCE_SEQ` 不去重不设唯一(v2 §3.2)。
|
|
||||||
- **写路径**:`persistNextStates` 是唯一写路径;引擎产生显式命令
|
|
||||||
(Unchanged/Set/Clear/Replace/Apply),序号 0 条目仅在整集合清除时翻译为 Clear,
|
|
||||||
混排 fail fast;异常对象 `"null"`/`{}`/空串 = 显式清除置 NULL。
|
|
||||||
- **事务**:PIPELINE_LOCK 行锁内复核快照身份(`schd_gen.last_message_id`)与当前态,
|
|
||||||
CAS 失败一律回滚 `FAILED(INFRA)`;提交后共享信箱回填失败落 `backfill_todo` 补偿重试,
|
|
||||||
成功终态不降级(v2 §5)。
|
|
||||||
- **读模型**:明细表为权威读;`flight_schd_display` 视图提供首/次资源与总数投影。
|
|
||||||
- **双库**:`SqlDialect` 接缝(PG 实装;`Oracle11gDialect` 为编译级交付),
|
|
||||||
11g 激活门控见 `db/migration/oracle11g/README.md`——现场 11.2 实测通过前不切换。
|
|
||||||
- **现行设计**:[flight-state.md](../flight-state.md)。
|
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ msgexchange-api 为成都机场 OMMS 消息交换服务(`com.gzzn.omms:msgexch
|
|||||||
3. `updatefltrBridge`:将各航班 `ABTM` 中的 `ABDG` **按序直接追加**到派生字段 `abdg`(代码不插入分隔符——分隔符依赖 `ABDG` 数据本身是否带逗号),拼接结果若以逗号结尾则**仅删除末尾一个逗号**;
|
3. `updatefltrBridge`:将各航班 `ABTM` 中的 `ABDG` **按序直接追加**到派生字段 `abdg`(代码不插入分隔符——分隔符依赖 `ABDG` 数据本身是否带逗号),拼接结果若以逗号结尾则**仅删除末尾一个逗号**;
|
||||||
4. 调用 `redisService.hmset("flightInfo", FLID→FLTR)` 写入航班集合。
|
4. 调用 `redisService.hmset("flightInfo", FLID→FLTR)` 写入航班集合。
|
||||||
|
|
||||||
说明:`RedisService.hmset` 实现为 `opsForHash().putAll`,仅新增/覆盖 field;新快照中未出现的旧 field 不会被删除,即 `flightInfo` 为合并写入语义,**并非整体替换**。快照差集清理须由新系统显式实现(见 6 节迁移验收边界)。
|
说明:`RedisService.hmset` 实现为 `opsForHash().putAll`,仅新增/覆盖 field;这是 legacy 行为记录,不构成新系统的设计依据。
|
||||||
|
|
||||||
刷新成功:调用 `sendDschd` 向 Kafka 主题 `msg` 发送日计划到达通知(`MSG` 仅保留 `META`,业务体为空),随后将该记录标记为已处理,返回成功。
|
刷新成功:调用 `sendDschd` 向 Kafka 主题 `msg` 发送日计划到达通知(`MSG` 仅保留 `META`,业务体为空),随后将该记录标记为已处理,返回成功。
|
||||||
|
|
||||||
@@ -233,7 +233,7 @@ msgexchange-api 为成都机场 OMMS 消息交换服务(`com.gzzn.omms:msgexch
|
|||||||
3. `hmset("flightInfo", FLID→FLTR)` 合并写入(新增/覆盖 field,不删除快照中未出现的旧 field);
|
3. `hmset("flightInfo", FLID→FLTR)` 合并写入(新增/覆盖 field,不删除快照中未出现的旧 field);
|
||||||
4. 成功后发送日计划到达通知至 Kafka `msg`,并标记已处理。
|
4. 成功后发送日计划到达通知至 Kafka `msg`,并标记已处理。
|
||||||
- 验收标准:
|
- 验收标准:
|
||||||
- Redis `flightInfo` 合并写入:报文内航班被新增/覆盖;快照中不存在而 Redis 已存在的旧航班不被清除(合并语义,非整体替换);
|
- Redis `flightInfo` 合并写入:报文内航班被新增/覆盖;该行为仅供 legacy 对拍使用;
|
||||||
- 主航班 `MAFL` 包含各共享航班的 `FLID` / `FLNO`;
|
- 主航班 `MAFL` 包含各共享航班的 `FLID` / `FLNO`;
|
||||||
- 各航班 `abdg` 为 `ABDG` 值按序直接追加的结果:分隔符依赖数据本身,代码不插入分隔符;仅当拼接结果以逗号结尾时删除末尾一个逗号。回放测试需按该真实机制设定期望(见 3.3);
|
- 各航班 `abdg` 为 `ABDG` 值按序直接追加的结果:分隔符依赖数据本身,代码不插入分隔符;仅当拼接结果以逗号结尾时删除末尾一个逗号。回放测试需按该真实机制设定期望(见 3.3);
|
||||||
- Kafka `msg` 收到仅含 `META` 的通知消息;
|
- Kafka `msg` 收到仅含 `META` 的通知消息;
|
||||||
@@ -484,7 +484,7 @@ msgexchange-api 为成都机场 OMMS 消息交换服务(`com.gzzn.omms:msgexch
|
|||||||
9. 明文口令直接存放于各环境 `application-*.yml`;默认激活环境为 dev(`spring.profiles.active=dev`)。
|
9. 明文口令直接存放于各环境 `application-*.yml`;默认激活环境为 dev(`spring.profiles.active=dev`)。
|
||||||
10. 忽略清单在 test 环境配置为 `error-*`,与其他环境(`eror-*`)不一致。
|
10. 忽略清单在 test 环境配置为 `error-*`,与其他环境(`eror-*`)不一致。
|
||||||
11. `hstCondition` 各阈值按毫秒计算(配置注释亦为毫秒),而相关代码注释存在单位表述不一致。
|
11. `hstCondition` 各阈值按毫秒计算(配置注释亦为毫秒),而相关代码注释存在单位表述不一致。
|
||||||
12. `updateByDaySchd` 经 `RedisService.hmset`(`putAll`)合并写入:新日计划快照中未出现的旧航班不会被清除(见 3.3)。如采用整体替换语义,新系统须显式清理差集并以回放测试固定预期。
|
12. `updateByDaySchd` 经 `RedisService.hmset`(`putAll`)合并写入;该实现细节仅描述 legacy 行为。
|
||||||
13. `FDELHandler` 对共享航班的删除同样调用 `sendMsg` 发送 `msg` 删除消息(与"共享航班不直接发送"的通用规则不一致)。
|
13. `FDELHandler` 对共享航班的删除同样调用 `sendMsg` 发送 `msg` 删除消息(与"共享航班不直接发送"的通用规则不一致)。
|
||||||
14. `FDELHandler` 删除共享航班、`ADFTHandler` 添加共享航班时,对主航班 `MAFL` 的修改均仅作用于内存对象并进入发送缓冲,未调用 `saveFltr` 写回 Redis;FDEL 元素比对使用 `==`(`MAFLDATA.getFlid()` 与 `FLTR.getFLID()` 均为 `BigInteger`,故为引用比较而非值比较)。属遗留缺陷,新系统应采用值相等比较并在同一原子状态变更中持久化主/共享航班关系。
|
14. `FDELHandler` 删除共享航班、`ADFTHandler` 添加共享航班时,对主航班 `MAFL` 的修改均仅作用于内存对象并进入发送缓冲,未调用 `saveFltr` 写回 Redis;FDEL 元素比对使用 `==`(`MAFLDATA.getFlid()` 与 `FLTR.getFLID()` 均为 `BigInteger`,故为引用比较而非值比较)。属遗留缺陷,新系统应采用值相等比较并在同一原子状态变更中持久化主/共享航班关系。
|
||||||
15. `/schd/sync` 时间解析使用 12 小时制 `hh`(无 AM/PM 标记),且对空值、区间、解析失败及服务返回值均无校验。
|
15. `/schd/sync` 时间解析使用 12 小时制 `hh`(无 AM/PM 标记),且对空值、区间、解析失败及服务返回值均无校验。
|
||||||
@@ -504,7 +504,7 @@ msgexchange-api 为成都机场 OMMS 消息交换服务(`com.gzzn.omms:msgexch
|
|||||||
|
|
||||||
### 6.2 迁移验收边界
|
### 6.2 迁移验收边界
|
||||||
|
|
||||||
1. **快照替换语义**:若日航班计划采用整体替换,须显式清理差集,并以回放测试固定「输入样本 → Redis 终态」预期(现役为合并语义,见 3.3)。
|
1. **日计划语义**:新系统的日计划处理规则以 [运营航班状态设计](../flight-state.md) 为准,不从 legacy Redis 行为推导。
|
||||||
2. **共享航班增删链路**:决定保留或消除 FDEL 对共享航班的通知(US-B1 例外);主/共享航班关系(ADFT 添加、FDEL 删除)须在同一原子状态变更中持久化(修复 ADFT/FDEL 未写回与 FDEL `==` 引用比较缺陷,见 5.7-14)。
|
2. **共享航班增删链路**:决定保留或消除 FDEL 对共享航班的通知(US-B1 例外);主/共享航班关系(ADFT 添加、FDEL 删除)须在同一原子状态变更中持久化(修复 ADFT/FDEL 未写回与 FDEL `==` 引用比较缺陷,见 5.7-14)。
|
||||||
3. **可执行验收矩阵**:覆盖 3 个 SCHD 与 29 个 FLOP 子类型,维度为「输入样本 × Redis 状态变更 × Kafka 通知结果」;对当前无测试的关键路径(如 ACTT、CNCL、FDEL、RESP、DNLD、ADFT)补自动化用例。
|
3. **可执行验收矩阵**:覆盖 3 个 SCHD 与 29 个 FLOP 子类型,维度为「输入样本 × Redis 状态变更 × Kafka 通知结果」;对当前无测试的关键路径(如 ACTT、CNCL、FDEL、RESP、DNLD、ADFT)补自动化用例。
|
||||||
4. **入站可靠性**:每类消息的幂等键、重复投递与多实例并发行为。
|
4. **入站可靠性**:每类消息的幂等键、重复投递与多实例并发行为。
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
- 所有内部迁移只落自有 PG;共享 MySQL 不建表、不增列、不写历史表。本文用 `DATE_PROCESSED / STATUS` 表示逻辑字段,实际列名以库方契约为准。
|
- 所有内部迁移只落自有 PG;共享 MySQL 不建表、不增列、不写历史表。本文用 `DATE_PROCESSED / STATUS` 表示逻辑字段,实际列名以库方契约为准。
|
||||||
- 验收条目可按 `US-xx/条目号` 引用。故事较大时按下文子范围拆成小 PR,不把一个故事等同于一个提交。
|
- 验收条目可按 `US-xx/条目号` 引用。故事较大时按下文子范围拆成小 PR,不把一个故事等同于一个提交。
|
||||||
|
|
||||||
**存储基线**:[单库权威决策](decision-flight-state.md) 已采纳:当前 PG 主表与明细表是状态权威,Redis 不参与动态写路径。Oracle 11g 是尚待完整适配的部署目标。航班状态设计和当前缺口见 [flight-state.md](flight-state.md)。
|
**存储基线**:当前 PG 主表与明细表是状态权威,Redis 不参与动态写路径。Oracle 11g 是尚待完整适配的部署目标。航班状态设计和当前缺口见 [flight-state.md](flight-state.md)。
|
||||||
|
|
||||||
## 2. 建议实施顺序
|
## 2. 建议实施顺序
|
||||||
|
|
||||||
@@ -126,18 +126,18 @@
|
|||||||
|
|
||||||
| 报文 | 路由 | 请求状态 | 无匹配时 |
|
| 报文 | 路由 | 请求状态 | 无匹配时 |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| `SCHD-DNLD` | SnapshotFlow | 不更新请求 | 不要求开放请求 |
|
| `SCHD-DNLD` | ScheduleProcessor | 不更新请求 | 不要求开放请求 |
|
||||||
| `SCHD-RESP` | 匹配守卫后进入 SnapshotFlow | 成功提交时匹配 RQFD → DONE | SKIPPED、审计,禁止更新快照 |
|
| `SCHD-RESP` | 匹配守卫后进入 ScheduleProcessor | 成功提交时匹配 RQFD → DONE | SKIPPED、审计,禁止更新快照 |
|
||||||
| `SCHD-ADFT` | US-05 增量 Handler | 不更新请求 | 不适用 |
|
| `SCHD-ADFT` | US-05 增量 Handler | 不更新请求 | 不适用 |
|
||||||
|
|
||||||
**验收标准**
|
**验收标准**
|
||||||
|
|
||||||
1. RESP/DNLD 共用流式解析、整包校验和规范化;校验失败不发布半包,旧快照保持可用。
|
1. RESP/DNLD 共用流式解析、整包校验和规范化;校验失败不发布半包,旧快照保持可用。
|
||||||
2. RESP 仅匹配未过期、已发送的开放 RQFD;`DTTM < SENT_AT`、已过期、已被替代或无匹配时,不写业务状态,记录跳过原因。
|
2. RESP 仅匹配未过期、已发送的开放 RQFD;`DTTM < SENT_AT`、已过期、已被替代或无匹配时,不写业务状态,记录跳过原因。
|
||||||
3. 在自有 PG 单事务内,批处理写入新代 `FLIGHT_SCHD`、按代域化差删旧代航班并执行 SQL CAS 推进 `SCHD_GEN` 版本;删除集只来自上一代成员,不误删集合外的 ADFT 航班。
|
3. 在自有 PG 单事务内,批处理写入已校验的 `FLIGHT_SCHD` 航班状态与资源明细;本次日计划中未出现的航班不因此被删除。
|
||||||
4. 在同一 PG 事务中提交 `FLIGHT_SCHD` 变更、`MSG_EVENT` 待发通知与 `PROC_STATE(SUCCEEDED)`;匹配 RESP 同事务完成请求并置 `DONE`;事务提交后执行信箱回填。
|
4. 在同一 PG 事务中提交 `FLIGHT_SCHD` 变更、`MSG_EVENT` 待发通知与 `PROC_STATE(SUCCEEDED)`;匹配 RESP 同事务完成请求并置 `DONE`;事务提交后执行信箱回填。
|
||||||
5. 相同报文重放不二次增代或删数据;单事务崩溃整体回滚,重放幂等(FS6 门槛 1/2/3 验证通过)。
|
5. 相同报文重放不二次写入或重复发事件;单事务崩溃整体回滚,重放幂等。
|
||||||
**当前基础与落点**:`processing/SnapshotFlow.kt` 的 staging 为占位,主处理只分流 DNLD,gen 走进程内过渡仓储。需补 RESP 路由、版本协议及 `REQ_TRACK` 应答关联字段和事务测试。
|
**当前基础与落点**:主处理只分流 DNLD;需补 RESP 路由、`REQ_TRACK` 应答关联字段和事务测试。
|
||||||
|
|
||||||
**前置**:US-03、US-08 请求登记/匹配基础;Q1、Q5。
|
**前置**:US-03、US-08 请求登记/匹配基础;Q1、Q5。
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user