分布式事务不是选修课,是必修课
你在电商系统里买一件商品,下单、扣库存、付款,这三个操作可能分布在订单服务、库存服务和支付服务中。如果付款失败了,但库存已经被扣了,用户肯定炸锅。这时候,靠数据库本地事务已经搞不定了,得靠分布式事务来兜底。
常见的几种解决方案
架构师面对这种问题,不会一上来就写代码,而是先看场景适不适合用哪种方案。比如,强一致性要求高的场景,像银行转账,就不能容忍中间状态;而像优惠券发放这种,稍微延迟一会儿也行,可以用最终一致性。
两阶段提交(2PC):老派但可靠
2PC 分为准备阶段和提交阶段。所有参与节点先投票,都同意才真正执行。听起来稳,但问题也不少:协调者单点故障、同步阻塞、数据不一致风险依然存在。适合内部系统,不适合高并发互联网场景。
<!-- 简化流程示意 -->
协调者:"准备提交吗?"
参与者A:"OK"
参与者B:"OK"
协调者:"执行提交"
参与者A/B:"已提交"
TCC:手动控制三步走
TCC 是 Try-Confirm-Cancel 的缩写。比如下单,Try 阶段冻结库存,Confirm 阶段确认扣减,Cancel 阶段释放冻结。业务侵入性强,但灵活可控。适合对一致性要求极高、逻辑清晰的场景。
举个例子,你订酒店房间,Try 先锁定房型,付款成功就 Confirm 扣掉名额,失败就 Cancel 放回去。整个过程你自己把控,不怕卡在中间。
基于消息队列的最终一致性
很多互联网公司喜欢这条路。比如用户下单后,发一条消息到 MQ,库存服务消费消息去扣库存。哪怕库存服务暂时挂了,消息也不会丢,等它恢复就能继续处理。
关键点在于:消息要持久化,消费要幂等。不然同一条消息被处理两次,库存就多扣了。所以你在写消费逻辑时,得加个判断,比如根据订单ID查一下是否已经处理过。
Saga 模式:长事务拆成小步骤
Saga 把一个大事务拆成多个可补偿的子事务。每个步骤都有对应的回滚操作。比如 A → B → C,如果 C 失败,就依次执行 C⁻¹ → B⁻¹ → A⁻¹ 回滚。
这就像你坐高铁出差,先买票、再打车去车站、再进站安检。万一安检没通过,就得退票、取消打车。每一步都要有退路,整个流程才能安全。
选型要看实际场景
不是越复杂越好。小团队做内部系统,用消息队列+人工对账也能撑一阵子。大平台追求高可用,可能会上 Seata 这类框架,结合 TCC 或 Saga 自动管理。
架构师的关键能力,是判断什么时候该用什么方案,而不是照搬别人的经验。你得清楚自己的业务容忍什么、怕什么、能承受什么代价。