多源数据冲突时优先级规则怎么设计?
简化版
多源冲突不能只规定“某系统永远优先”或“最后写入优先”。 先按字段定义权威来源,再比较业务版本、事件因果和状态机合法迁移;无法判断时才使用确定性兜底。 规则必须版本化、可解释、可审计,高风险冲突进入人工复核。
详细版
建立字段级 ownership:客户等级以 CRM 为准,实名状态以认证系统为准,订单状态以订单系统为准。 同一来源内部用单调版本或 CAS;跨来源事件携带 source、entityVersion、eventId 和 occurredAt。 物理时间只能辅助,因为时钟漂移和消息延迟使“后到”不等于“后发生”。 无法自动合并时保存冲突版本和证据,不静默丢弃。
完整版教学
一、先确定字段所有权
一个业务实体常由多个系统共同写入。 不同字段可能有不同 owner,整行设单一来源优先会覆盖合法数据。 优先级首先来自数据所有权,其次才是版本与时间。
冲突解决是业务语义问题,不能只靠数据库更新时间。
二、规则层级
| 层级 | 判断依据 |
|---|---|
| 1 | 字段权威来源 |
| 2 | 状态机合法性 |
| 3 | 同源单调版本 |
| 4 | 因果关系 |
| 5 | 业务兜底或人工 |
每层输出选择理由和被拒绝版本。
三、同源版本
同一来源为实体分配递增 version。 消费者仅在 incomingVersion 大于 storedVersion 时更新。
UPDATE entity
SET value=?, version=?
WHERE id=? AND version < incomingVersion
零行受影响表示旧事件或冲突,需要分类记录。
四、跨源时间陷阱
系统 A 时钟快 20 秒,旧状态可能带更大 timestamp。 消息后到达也不代表业务后发生。 优先使用业务序列、上游 revision 或因果元数据。 确需 LWW 时固定平局规则并承认丢更新风险。
五、状态机保护
订单 CREATED→PAID→SHIPPED 有合法方向。 迟到 CREATED 不能覆盖 SHIPPED,即使时间戳更大。 退款、撤销等分支要显式建模。 不能用枚举数字大小代表业务先后。
六、合并与冲突保留
并发更新不同字段时可按 ownership 合并。 修改同一不可合并字段时保存 siblings 和来源。 购物车集合可合并,余额不能随意取最大。 高风险对象转人工并暂停自动覆盖。
七、审计与测试
记录输入版本、来源、规则版本、输出和拒绝原因。 监控冲突率、自动解决比例和人工积压。 用乱序、重复、同时间戳、时钟回拨和规则升级做回放测试。 规则修改前用历史冲突离线演算影响。
八、常见误区与追问
- 误区:更新时间最大的一定最新。 跨系统时钟不可靠。
- 误区:整表只需一个权威系统。 字段所有权可能不同。
- 误区:枚举值越大状态越新。 应按状态机判断。
- 误区:冲突必须自动选一个。 不可安全合并时应人工处理。
- 追问:规则变化怎么办? 规则版本化并按需重算历史。
- 追问:同版本不同内容怎么办? 视为分叉,保留证据并告警。
- 追问:如何保证确定性? 固定规则版本、平局规则和规范化输入。
九、加强记忆
- 先定字段 owner。
- 状态机挡非法回退。
- 同源按版本,跨源按因果。
- 时间戳只是有风险的兜底。
- 不可合并冲突保留证据并人工裁决。