分布式事务总是对不上账:从强一致到最终一致的架构选择
针对跨服务写入部分成功、补偿失败和对账困难,解释本地事务、事件驱动、Saga 与对账修复的选择方法。
问题现象:一个业务动作跨越多个服务
订单创建、库存扣减、优惠券核销和支付记录可能分布在不同数据库。任何一步超时,都可能出现部分成功。试图把所有服务放进一个强一致事务,会增加耦合、锁时间和故障范围。正确做法是先区分哪些数据必须立即一致,哪些可以在可控时间内收敛。
先把单服务本地事务做好
每个服务内部应确保状态变更和待发送事件原子提交,可使用本地消息表记录事件,再由后台任务可靠投递。消费者必须幂等,并记录处理状态。这样即使消息系统短暂不可用,事件也不会随着业务提交而丢失。
最终一致需要明确状态机
不要把“最终一致”理解为等待系统自己恢复。业务应定义处理中、成功、失败、待补偿等状态,以及每个状态允许的下一步。Saga 适合把长事务拆成多个本地事务,并为已完成步骤定义补偿动作。但补偿不一定是简单反操作,例如商品已经发货时,退款不能等同于删除订单。
超时不代表失败
调用方超时后,下游可能已经完成操作。此时立即重试可能造成重复扣款。接口要支持幂等键和结果查询,调用方在未知状态下先查询再决定重试。对外部支付等不可控系统,应保存请求号、回调和主动查询结果,建立完整证据链。
对账是架构组成部分
再完善的在线流程也需要周期对账。按业务唯一键比较各系统状态,发现差异后自动修复或进入人工工单。问:什么时候必须强一致?答:无法接受中间状态且参与方可由同一事务管理时。问:最终一致多久算最终?答:必须有业务承诺,例如一分钟内收敛,并用指标监控超时未收敛数量。
文章回复
0 条公开回复