从 37 笔对不上的订单说起
系列开头,老王被 37 笔「订单创建了库存没扣」的订单逼到墙角;十八篇之后,他的系统里消息表、TCC 冻结、对账任务各司其职,季度审计的差错率稳定在百万分之一以下。收官这篇不写新知识,把十八篇串成一张作战地图——下次账对不上,先翻这张图,再动手。
症状速查表
| 症状 / 诉求 | 去哪找药 | 一句话药方 |
|---|---|---|
| 跨服务数据对不上 | 第 1 篇 | 先接受三态现实,再谈方案 |
| 搞不清一致性怎么取舍 | 第 2 篇 | P 没得选,C 与 A 之间按业务选 |
| 低并发要跨库强一致 | 第 3 篇 | 2PC/XA,接入便宜运行昂贵 |
| 高并发要预留资源 | 第 4 篇 | TCC,Try 冻结 Confirm 划账 |
| TCC 回滚诡异 | 第 5 篇 | 空回滚、幂等、悬挂一张控制表全防 |
| 长流程要能回退 | 第 6 篇 | Saga 状态机加逆序补偿 |
| 消息和业务不原子 | 第 7 篇 | 本地消息表同库同事务 |
| 不想养消息表 | 第 8 篇 | RocketMQ 事务消息加回查 |
| 通知外部系统 | 第 9 篇 | 阶梯重试尽力喊,查询口子留后门 |
| 重复扣款重复消费 | 第 10 篇 | 五大武器按场景上,唯一索引是最后的墙 |
| 框架怎么选 | 第 11 篇 | Seata 四问定模式 |
| AT 回滚报脏写 | 第 12 篇 | 全局锁防脏写,热点行换方案 |
| 余额更新排队 | 第 13 篇 | 缓冲记账、子账户、TCC 冻结按热度选 |
| 超时被判失败 | 第 14 篇 | 未知态先查询,重试退避加预算 |
| 注解失效 | 第 15 篇 | 七宗罪对号入座,边界小而纯粹 |
| 差异兜底 | 第 16 篇 | 独立数据源全量比对,差错三路分流 |
| 各种诡异事故 | 第 17 篇 | 七个坑,条条是纪律 |
三条铁律
铁律一:强一致是奢侈品,按数据重要性发放。能塞进单库单事务的,绝不用分布式方案;能用最终一致的,绝不上强一致——每一次提升一致性等级,都是拿可用性和吞吐去换。先问业务要不要,再问技术能不能。
铁律二:幂等是一切方案的地基。MQ 会重投、框架会重试、人会手抖、网络会重发——没有幂等,TCC、事务消息、对账重跑全是裸奔。幂等键用业务语义键,兜底用唯一索引。
铁律三:防御是概率,对账是确定性。无论防御多密,组合故障总会漏进差异;唯一能把「漏网」变成「必抓」的,是独立数据源的全量比对。对账系统不是可选项,是资金链路的强制项。
选型四步一分钟回顾
新场景从零选型的路径:一步——能拆回单库单事务吗?能,本地事务直接解决;二步——链路短且并发高吗?高并发资金类上 TCC,普通业务上 AT 或消息型;三步——流程长、周期跨天吗?是,Saga 状态机;四步——对象是外部系统吗?是,最大努力通知加查询接口。四步走完还没落地的,回到第 2 篇重新审视业务一致性需求——多半是需求本身写拧了。
上线检查清单
跨服务链路上线前十项检查:一,方案选定且写入设计文档;二,所有消费端幂等实现并做过并发压测;三,消息发送可靠化(消息表或事务消息);四,超时按下游 P99 定,未知态走查询;五,重试退避加抖动、设总预算;六,协调者(TC)高可用部署并演练过主备切换;七,对账任务上线,差错率进监控大盘;八,事务边界过完五问清单;九,长事务监控告警就位;十,全链路故障演练跑过一遍。十项全绿再上生产——分布式事务最怕的不是选错方案,是「差不多就行」。
系列之外
Redis 缓存、MySQL 实战、消息队列、Elasticsearch 检索、分布式 ID,加上这套分布式事务,六个系列把后端主干地图又拼上一大块。还有一块硬骨头与本系列血脉相连——分布式锁与一致性协议:TCC 的防悬挂、Seata 的全局锁、缓存的双删,背后都是同一个问题的不同答案:多个节点怎么对一件事达成一致。ZooKeeper 的 ZAB、etcd 的 Raft,是下一个系列的主角。老王的 503 咖啡馆继续开门,我们下个系列见。
小结
收官一句话:一致性按需发放、幂等打地基、对账做确定性兜底——三条铁律扛走,十八篇的细节都在这张地图上,用的时候来查。分布式事务实战系列,全十八篇,完结撒花。
评论 (0)