为什么分布式事务如此困难

分布式事务的核心挑战在于CAP定理的固有限制。在分区容忍性(P)必须保证的前提下,我们只能在一致性(C)和可用性(A)之间做出取舍。随着微服务架构的普及,单一业务操作往往需要跨越多个服务、多个数据库,传统的ACID事务模型在分布式环境下无法直接应用。

具体而言,分布式事务面临以下核心难题:

  • 网络不确定性:消息丢失、延迟、重复、乱序等问题在分布式环境中无法避免
  • 节点故障:任何参与者、协调者随时可能宕机或无法响应
  • 性能瓶颈:两阶段提交的同步阻塞特性在高并发场景会成为严重的性能瓶颈
  • 时钟漂移:不同节点的物理时钟存在偏差,影响基于时间戳的排序和可见性判断
  • 隔离级别不足:大多数分布式方案只能提供读已提交或更弱的隔离级别

经典方案:2PC与3PC

两阶段提交(2PC, Two-Phase Commit)是分布式事务的经典协议,由IBM在1970年代提出。它引入一个协调者(Coordinator)和多个参与者(Participants),通过两个阶段的协议保证所有节点要么全部提交、要么全部回滚。

阶段一:投票阶段(Voting Phase):协调者向所有参与者发送PREPARE请求,参与者执行事务操作(写入undo/redo日志),但不提交。参与者将执行结果(YES或NO)返回给协调者。

阶段二:提交阶段(Commit Phase):如果所有参与者都返回YES,协调者发送COMMIT指令,参与者正式提交事务;如果有任何一方返回NO或超时,协调者发送ROLLBACK指令,参与者回滚事务。

2PC的最大问题是同步阻塞和单点故障:

  • 所有参与者在投票阶段会持有锁等待协调者决策,高并发场景下数据库连接和锁资源快速耗尽
  • 协调者宕机时,参与者无法获取最终决策,事务将无限期阻塞(需要人工介入或超时机制打破)
  • 网络分区导致协调者与参与者失联时,已进入提交阶段的事务可能产生脑裂(split-brain)

三阶段提交(3PC, Three-Phase Commit)通过引入PRE-COMMIT阶段和超时机制来缓解2PC的阻塞问题:

阶段一CAN_COMMIT:协调者询问参与者是否能执行业务(轻量级检查,不加锁)

阶段二PRE_COMMIT:所有参与者同意后,协调者发送预提交指令,参与者执行操作但不提交

阶段三DO_COMMIT:所有预提交成功后,协调者发送最终提交指令

3PC通过当协调者故障时,参与者在超时后默认提交(第一阶段已确认参与者状态)来避免无限阻塞,但数据不一致的风险在网络分区时依然存在。

TCC(Try-Confirm-Cancel)灵活事务

TCC是一种业务层面的分布式事务协议,通过将业务操作拆分为三个阶段来实现最终一致性:

Try阶段:预留资源并完成业务规则校验(如检查账户余额是否充足、库存是否足够、是否超卖等),但不实际扣减。例如电商下单场景,try操作可能是冻结资金、预占库存、生成订单(状态为"待支付")。

Confirm阶段:在try成功后调用,正式完成业务操作。Confirm操作应该是幂等的,能够安全重试。例如扣减冻结资金、减少预占库存数量、将订单状态改为"已确认"。

Cancel阶段:当Confirm失败或业务异常时调用,回滚try阶段预留的资源。Cancel同样需要幂等性,能安全重试。例如释放冻结资金、归还预占库存、将订单状态改为"已取消"。

TCC的优势在于完全不依赖数据库事务,而是通过业务逻辑实现分布式协作。但这意味着侵入性强——每个参与服务都需要实现try、confirm、cancel三个接口,业务复杂度显著增加。

主流的TCC框架包括Seata(阿里开源)、ByteTCC、EasyTransaction等。Seata的AT模式可以零侵入地使用数据库的undo log实现两阶段提交,是TCC的简化替代方案。

Saga模式:长事务的最终一致性

Saga是由Garcia-Molina在1987年提出的长事务管理模型,最初用于银行数据库的批处理场景。在微服务架构中,Saga被重新定义为协调多个服务间一系列本地事务的模式。

核心理念:一个长时间运行的分布式事务(如跨5个服务的订单创建流程),被拆分为一系列按顺序执行的事务操作(T1, T2, T3, T4, T5),每个操作对应一个补偿操作(C5, C4, C3, C2, C1)。如果第3步执行失败,则按逆序执行补偿操作(C2, C1)来回滚之前已完成的步骤。

编排模式(Choreography):每个服务发布事件,其他服务监听事件并执行下一个步骤。没有中央协调者,依赖事件驱动的消息传递。优点是实现简单,缺点是流程难以理解和调试(需要追踪事件流才能知道剩余步骤)。

编排模式(Orchestration):引入中心化的Saga编排器,由它负责调用各个服务、监听响应、推进流程或触发补偿。流程清晰可控,适合复杂业务场景,缺点是引入了单点(编排器本身)。

常见的Saga实现框架:

  • Eventuate Tram Sagas(Java生态,支持Choreography和Orchestration两种模式)
  • Seata Saga(支持状态机引擎定义流程)
  • Camunda / Flowable(BPMN工作流引擎,支持Saga的编排模式)
  • MicroProfile LRA(Jakarta EE标准,基于REST的Saga实现)

Saga的挑战

  • 隔离性缺失:Saga的每个本地事务立即提交,中间状态对其他事务可见,可能导致脏读
  • 补偿复杂性:退款、退货等业务操作的补偿可能是不可逆的(如已发货的商品只能通过物流追踪)
  • 幂等性保证:报文和重试机制要求每个步骤和补偿操作必须是幂等的

消息驱动的事务方案:本地消息表与事务消息

本地消息表(Local Transaction Table)是一种朴素的可靠消息最终一致性方案。核心思想是将业务操作和消息写入放在同一个本地事务中(在业务库中增加一个transaction_message表),然后由额外的投递服务异步推送消息到MQ。

流程:1)写入业务数据和消息记录(同一事务)→ 2)定时任务或独立服务扫描未投递的消息 → 3)投递到MQ → 4)消费方处理业务并ACK(或重试/报错)。

事务消息(如RocketMQ的Half Message)是消息中间件内置的事务支持。核心流程:

1)发送Half消息(队列不可见,消费者无法消费)→ 2)执行本地事务 → 3)提交Local Transaction结果(COMMIT/ROLLBACK)→ 4)COMMIT后消息对消费者可见,ROLLBACK后消息删除

如果本地事务结果未定,Broker会通过回溯机制检查本地事务状态(调用producer的回查接口),实现最终一致性。

NewSQL时代的分布式事务

NewSQL数据库通过重新设计架构,在分布式环境下实现了跨越多个节点的ACID事务:

Google Spanner:基于TrueTime API(GPS + 原子钟)实现全球分布的外部一致性(External Consistency),是分布式事务的理论到工程的巅峰之作。它通过Commit Wait机制保证线性一致性,是高隔离性的代价是写入延迟(10-100ms全球部署)。

TiDB:基于Percolator事务模型(Google早期论文实现),支持乐观锁和悲观锁两种模式。通过PD(Placement Driver)调度多副本(Raft协议),提供Snapshot隔离级别。

CockroachDB:完全兼容PostgreSQL协议的多活数据库,使用并行提交(Parallel Commits)优化两阶段提交。通过SERIALIZABLE隔离级别和可串行化快照解决写倾斜问题。

YugaByte DB:基于DocDB的分布式文档存储之上构建SQL层,支持Redis和Cassandra两种API。通过DocDB的事务管理器实现跨行ACID,延迟比Spanner低(通常10ms以内单REGION)。

方案选型与工程权衡

没有银弹般的分布式事务方案,每种方案都有其适用场景和代价。选型时应该综合考虑业务特性、性能要求、团队技术栈和运维成本:

2PC:适合强一致性要求高的传统系统(如金融核心交易),参与者少(2-3个)、事务短(秒级)、并发低(TPS小于1000)。注意处理好协调者单点故障问题。

TCC:适合跨微服务的准实时业务(如电商支付、充值),需要业务方主动配合实现三接口。适合对隔离性有一定要求但不需要串行化的场景。

Saga:适合长流程的业务编排(如旅游预订:机票+酒店+租车+保险),可接受数据最终一致,补偿逻辑可业务定义。

本地消息表 / 事务消息:适合通知型业务(如短信推送、邮件发送、积分变动),对实时性要求不高,最终一致即可。

NewSQL:适合大型OLTP系统,无法接受数据不一致,且有能力承担数据库迁移成本。强烈建议新项目直接采用NewSQL方案。

总结

分布式事务是分布式系统中最复杂的设计之一。从2PC的强一致性,到TCC的业务级原子性,到Saga的最终一致性,再到NewSQL的工程化极致,不同方案恰如光谱上的不同频段。关键是理解每种方案背后的一致性假设和性能边界,根据业务的真实需求做出取舍。

值得欣慰的是,随着分布式共识算法(Raft/Paxos)、云原生数据库(TiDB/CockrogressDB)和事件驱动架构(CQRS/Event Sourcing)的成熟,我们正处在一个分布式事务越来越可控的时代——只要付出合理的成本,选择正确的方案,分布式事务的建设难度正降到可管理的范围内。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部