分布式事务核心概念
大家好,我是老张。今天咱们聊聊分布式事务。说实话,这玩意儿是交易系统里最让人头疼的部分之一。我在金融系统里摸爬滚打十几年,见过太多因为事务没处理好导致的资金对不齐、订单状态混乱的惨案。嗯,咱们先从最基础的概念说起。
什么是分布式事务?
简单说,分布式事务就是跨多个服务、多个数据库的事务操作。你想想看,一个下单操作,可能要扣库存、扣余额、生成订单、发消息通知。这些操作分散在不同的服务里,怎么保证它们要么全成功,要么全失败?
我习惯把分布式事务理解成「多人协作的接力赛」。每个人跑好自己的那段,但最后必须同时到达终点。如果有人掉棒了,前面跑的人也得退回来重跑。这就是分布式事务要解决的问题。
核心目标:保证跨多个独立节点的数据操作,在最终结果上保持一致性。说白了,就是让分布在不同机器上的数据,看起来像在同一个数据库里操作一样。
两阶段提交(2PC)协议详解
2PC 是最经典的分布式事务协议。我在早期做银行核心系统时,用的就是这套方案。它分两个阶段:
第一阶段:准备阶段(投票阶段)
协调者问所有参与者:「我要提交事务了,你们准备好了吗?」每个参与者回答「准备好了」或者「不行,我这儿出问题了」。
第二阶段:提交阶段(执行阶段)
如果所有人都说准备好了,协调者就通知大家:「好,正式提交!」如果有人说不,协调者就通知大家:「取消,回滚!」
听起来很简单对吧?但实际坑很多。我曾经遇到过一个问题:协调者发完「准备」消息后,自己挂了。所有参与者都处于「准备好了但没收到下一步指令」的状态,资源锁着释放不了。这就是 2PC 的阻塞问题。
避坑指南:我曾经在某个支付系统中,因为协调者单点故障,导致一批订单锁了整整 30 分钟。后来我们加了超时机制和重试策略,才勉强解决。但 2PC 的阻塞本质是无法完全消除的。
2PC 的优缺点很明显:
| 优点 | 缺点 |
|---|---|
| 原理简单,容易实现 | 同步阻塞,性能差 |
| 强一致性保证 | 协调者单点故障 |
| 大多数数据库原生支持 | 数据不一致风险(第二阶段部分失败) |
三阶段提交(3PC)协议改进
3PC 是 2PC 的升级版。它多了一个阶段,目的是解决 2PC 的阻塞问题。你想想看,2PC 里参与者一旦说「准备好了」,就只能等协调者的指令。3PC 加了个「预提交」阶段,让参与者有更多自主权。
三个阶段分别是:
- CanCommit(询问阶段):协调者问大家:「能不能提交?」参与者回答「能」或「不能」。
- PreCommit(预提交阶段):协调者说:「好,准备提交,但先别真提交。」参与者执行预操作,比如写日志、锁资源。
- 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。关键是要理解你的业务场景,然后选择最合适的方案。别盲目追求新技术,稳定才是第一位的。
公众号:蓝海资料掘金营,微信deep3321