分布式事务核心概念

大家好,我是老张。今天咱们聊聊分布式事务。说实话,这玩意儿是交易系统里最让人头疼的部分之一。我在金融系统里摸爬滚打十几年,见过太多因为事务没处理好导致的资金对不齐、订单状态混乱的惨案。嗯,咱们先从最基础的概念说起。

什么是分布式事务?

简单说,分布式事务就是跨多个服务、多个数据库的事务操作。你想想看,一个下单操作,可能要扣库存、扣余额、生成订单、发消息通知。这些操作分散在不同的服务里,怎么保证它们要么全成功,要么全失败?

我习惯把分布式事务理解成「多人协作的接力赛」。每个人跑好自己的那段,但最后必须同时到达终点。如果有人掉棒了,前面跑的人也得退回来重跑。这就是分布式事务要解决的问题。

核心目标:保证跨多个独立节点的数据操作,在最终结果上保持一致性。说白了,就是让分布在不同机器上的数据,看起来像在同一个数据库里操作一样。

两阶段提交(2PC)协议详解

2PC 是最经典的分布式事务协议。我在早期做银行核心系统时,用的就是这套方案。它分两个阶段:

第一阶段:准备阶段(投票阶段)

协调者问所有参与者:「我要提交事务了,你们准备好了吗?」每个参与者回答「准备好了」或者「不行,我这儿出问题了」。

第二阶段:提交阶段(执行阶段)

如果所有人都说准备好了,协调者就通知大家:「好,正式提交!」如果有人说不,协调者就通知大家:「取消,回滚!」

听起来很简单对吧?但实际坑很多。我曾经遇到过一个问题:协调者发完「准备」消息后,自己挂了。所有参与者都处于「准备好了但没收到下一步指令」的状态,资源锁着释放不了。这就是 2PC 的阻塞问题。

避坑指南:我曾经在某个支付系统中,因为协调者单点故障,导致一批订单锁了整整 30 分钟。后来我们加了超时机制和重试策略,才勉强解决。但 2PC 的阻塞本质是无法完全消除的。

2PC 的优缺点很明显:

优点 缺点
原理简单,容易实现 同步阻塞,性能差
强一致性保证 协调者单点故障
大多数数据库原生支持 数据不一致风险(第二阶段部分失败)

三阶段提交(3PC)协议改进

3PC 是 2PC 的升级版。它多了一个阶段,目的是解决 2PC 的阻塞问题。你想想看,2PC 里参与者一旦说「准备好了」,就只能等协调者的指令。3PC 加了个「预提交」阶段,让参与者有更多自主权。

三个阶段分别是:

  1. CanCommit(询问阶段):协调者问大家:「能不能提交?」参与者回答「能」或「不能」。
  2. PreCommit(预提交阶段):协调者说:「好,准备提交,但先别真提交。」参与者执行预操作,比如写日志、锁资源。
  3. DoCommit(正式提交阶段):协调者说:「现在正式提交!」或者「取消!」

3PC 最大的改进是引入了超时机制。如果参与者在预提交阶段后没收到协调者的指令,它会自动提交。这避免了 2PC 里无限等待的问题。

但说实话,3PC 在实际项目中用得不多。为什么?因为它虽然解决了阻塞问题,但引入了新的数据不一致风险。比如参与者自动提交了,但协调者后来通知回滚,那就乱套了。

我的经验:我个人习惯在金融交易系统中慎用 3PC。它的自动提交机制在资金类场景下风险太高。我宁愿接受 2PC 的阻塞,也不愿冒资金对不齐的风险。

TCC 模式原理

TCC 是 Try-Confirm-Cancel 的缩写。这是我目前在交易系统中用得最多的方案。它把每个操作拆成三个阶段:

  • Try(预留资源):比如扣库存时,先冻结库存,不真扣。
  • Confirm(确认执行):如果所有 Try 都成功,就执行 Confirm,真正扣库存。
  • Cancel(取消回滚):如果某个 Try 失败,就执行 Cancel,释放预留的库存。

TCC 的好处是业务侵入性强,但性能好,没有 2PC 的阻塞问题。每个阶段都是独立的网络调用,不会长时间锁资源。

我记得有一次做秒杀系统,用 2PC 的话,库存锁住的时间太长,导致大量请求超时。后来改成 TCC,Try 阶段只做冻结,Confirm 阶段才真正扣减,性能提升了 3 倍多。

核心要点:TCC 要求每个业务操作都要实现 Try、Confirm、Cancel 三个接口。这增加了开发工作量,但换来了更好的性能和可用性。

TCC 的 Cancel 操作一定要能正确处理。我曾经见过一个案例:Cancel 接口里调用了第三方服务,结果第三方挂了,Cancel 失败,导致资源一直冻结着。后来我们给 Cancel 加了重试和幂等机制,才彻底解决。

三种协议对比

协议 一致性 性能 实现复杂度 适用场景
2PC 强一致性 低(阻塞) 传统金融、对账系统
3PC 最终一致性 非核心链路、可容忍短暂不一致
TCC 最终一致性 高并发交易、秒杀、支付

嗯,这三种方案没有绝对的好坏。我个人的选择标准是:如果业务要求强一致性,且并发不高,用 2PC。如果追求高性能,能接受最终一致性,用 TCC。3PC 嘛,我一般只在特定场景下用,比如跨机房部署时。

最后说一句,分布式事务没有银弹。每种方案都有 trade-off。关键是要理解你的业务场景,然后选择最合适的方案。别盲目追求新技术,稳定才是第一位的。

分布式事务核心概念知识体系 分布式事务 定义 跨服务/跨数据库 要么全成功要么全失败 两阶段提交(2PC) 准备阶段 → 提交阶段 强一致性,但阻塞 三阶段提交(3PC) 增加预提交阶段 解决阻塞,有风险 TCC模式 Try → Confirm → Cancel 高性能,业务侵入强 没有银弹,根据场景选择最合适的方案

公众号:蓝海资料掘金营,微信deep3321