本文目录导读:

没有完全解决,也不可能被“一劳永逸”地解决。 分布式事务是一个经典难题,核心在于CAP理论(一致性、可用性、分区容错性)的权衡。
在实际工程中,根据业务场景选择合适的方案,分布式事务的问题已经有了非常成熟且可落地的解决方案,目前主要分为几大流派:
强一致性方案:XA协议(2PC/3PC)
- 思想:引入一个协调者,分两步(准备、提交)确保所有参与者要么都成功,要么都失败。
- 现状:基本被互联网公司抛弃,因为它是同步阻塞的,锁定资源时间长,性能极差,且协调者单点故障会导致整个系统卡死,只适用于银行、金融等对一致性要求极高、并发量极低的内部系统。
最终一致性方案(主流方案)
这是目前互联网高并发场景下的主要战场,核心思想是放弃强一致,保证最终一致,通过补偿机制来兜底。
A. TCC(Try-Confirm-Cancel)
- 思想:业务层面实现的三阶段模型,Try(预留资源)-> Confirm(确认执行)-> Cancel(回滚)。
- 优点:性能较高,粒度细,能控制锁范围。
- 缺点:业务侵入性极强,你需要为每个操作写 Try、Confirm、Cancel 三段逻辑,非常繁琐。
- 代表框架:Seata TCC 模式。
- 适用场景:金融转账、高一致性互联网电商的“下单扣库存”。
B. Saga
- 思想:将一个长事务拆分成多个子事务,每个子事务都有一个正向操作和反向补偿操作,如果某个子事务失败,依次执行前面所有子事务的反向操作来回滚。
- 优点:无锁、高性能,适合长事务。
- 缺点:不隔离,子事务提交后其他服务可见中间状态,需要业务容忍“脏读”,补偿逻辑复杂。
- 实现方式:主要有编排模式(一个协调器控制)和协同模式(服务间通过消息交互)。
- 适用场景:订单流程、预订系统(酒店+机票)。
C. 可靠消息最终一致性(最常用)
- 思想:利用消息队列(MQ)解耦,生产者确保消息100%投递给MQ,消费者消费成功后“半自动”回执,失败则重试或人工介入。
- 核心:
- 本地消息表:本地事务 + 消息表,确保写入业务数据的同时写入消息。
- 异步确保:MQ的
ACK机制 + 定时任务轮询未完成消息。
- 优点:松耦合、高性能、高可用。
- 缺点:事务时效性差(秒级),业务端需处理“重复消息”(幂等性)。
- 代表框架:RocketMQ(原生事务消息)、Seata AT 模式。
- 适用场景:绝大多数互联网业务(下单、积分、发券)。
D. 最大努力通知
- 思想:业务方发通知,不保证送达,只保证次数最多,通常配合回调接口 + 定时重试 + 人工兜底。
- 适用场景:非核心业务,如支付回调通知商户。
当前最流行的“答案”:Seata
目前国内分布式事务的事实标准是阿里的 Seata(Simple Extensible Autonomous Transaction Architecture),它把上述主流方案都封装好了,根据场景选择模式:
- AT模式(Automatic Transaction):基于本地事务 +
undo_log表,自动生成回滚SQL。侵入性低,性能高于XA低于TCC,是入门首选。 - TCC模式:需要手动写三段逻辑。
- Saga模式:适合长业务流程。
- XA模式:强一致,适合老系统。
什么时候用哪种?
| 业务场景 | 方案选择 | 原因 |
|---|---|---|
| 核心资金链路 (转账、支付) | TCC / XA | 要求高一致,能接受锁冲突。 |
| 高并发订单 (下单->减库存->积分) | 可靠消息 + Redis | 最终一致即可,性能优先。 |
| 长流程复杂业务 (预订、审批) | Saga(编排模式) | 事务链条长,需隔离允许补偿。 |
| 简单内部系统 | Seata AT | 自动回滚,开发快,性能可接受。 |
| 非核心通知 (短信、推送) | 最大努力通知 | 丢或不丢都无伤大雅。 |
分布式事务这个“问题”本身是无解的(CAP限制),但通过业务的妥协(接受最终一致)和成熟的中间件(Seata、RocketMQ),工程上已经完美解决了,现在项目选型,基本就是在 Seata(强一致/短事务)和 消息队列(最终一致/长事务)之间做选择。