1、分布式事务概述:为什么需要分布式事务、CAP理论与BASE理论、分布式事务的挑战与场景
1.1 为什么需要分布式事务
说实话,我刚入行那会儿,单体应用里一个@Transactional注解就能搞定所有事务问题。但后来业务规模上来了,数据库扛不住了,不得不拆库拆表,甚至拆成微服务。这时候问题就来了——原来在一个数据库里能保证的ACID,现在跨了多个服务、多个数据库,怎么保证数据一致性?
举个例子。我在做电商系统时,用户下单这个操作,涉及订单服务、库存服务、账户服务。订单扣款成功,但库存扣减失败,或者账户扣款失败——你想想看,这钱扣了货没发,用户不投诉才怪。这就是分布式事务要解决的核心问题:在分布式环境下,保证多个独立节点的数据最终一致。
说白了,分布式事务就是一套协调机制。它让多个服务像一个人一样行动,要么全成功,要么全回滚。但现实没那么美好,因为网络会抖、节点会挂、超时会发生。嗯,这里要注意,分布式事务不是银弹,它是有代价的。
1.2 CAP理论与BASE理论
聊分布式事务,绕不开CAP。我记得刚接触这个概念时,觉得它就是个理论玩具。直到有一次线上事故,让我彻底明白了它的分量。
1.2.1 CAP理论
CAP理论说,一个分布式系统最多只能同时满足三项中的两项:
- C(Consistency)一致性:所有节点在同一时刻看到的数据是一样的。你写入了A节点,读B节点必须能读到最新数据。
- A(Availability)可用性:每个请求都能收到一个非错误的响应,不管成功还是失败。说白了,系统不能挂。
- P(Partition Tolerance)分区容错性:网络出现分区(节点间通信断了),系统还能继续工作。
你可能会问:为什么只能选两个?我举个例子。假设两个节点之间网络断了(分区发生了)。这时候你往节点1写数据,节点2收不到同步。如果你要保证一致性,节点2就不能对外提供服务(牺牲可用性)。如果你要保证可用性,节点2就得继续响应请求,但数据可能不一致(牺牲一致性)。
我在项目中遇到过这样的场景:配置中心这种系统,我选CP,宁可暂时不可用,也不能让配置乱掉。但像用户点赞这种场景,我选AP,少几个赞无所谓,系统不能挂。
1.2.2 BASE理论
BASE理论是CAP的实践延伸。它说:既然强一致性做不到,那就退而求其次,追求最终一致性。
BASE包含三层意思:
- BA(Basically Available)基本可用:系统允许部分功能降级,比如双十一时,查询历史订单可以延迟几秒,但不能查不到。
- S(Soft State)软状态:允许系统存在中间状态,数据同步过程中,不同节点的数据可以不一致。
- E(Eventually Consistent)最终一致性:经过一段时间后,所有节点的数据最终会达成一致。
说白了,BASE就是告诉我们要务实。强一致性太贵了,我们付不起那个性能代价。我曾经在一个金融项目中,硬要用两阶段提交保证强一致,结果TPS直接掉到两位数,被业务方骂惨了。后来改成最终一致性加补偿机制,性能上去了,数据也没出过问题。
1.3 分布式事务的挑战与场景
1.3.1 核心挑战
做分布式事务,说白了就是在跟这几个问题死磕:
- 网络不可靠:请求可能丢、可能重、可能延迟。你发一个提交指令,对方收到了吗?不知道。你发一个回滚指令,对方执行了吗?也不知道。
- 节点故障:服务可能突然挂了,数据库可能宕机了。事务进行到一半,协调者挂了怎么办?参与者挂了怎么办?
- 数据一致性:多个服务各自维护自己的数据,怎么保证它们要么一起变,要么都不变?
- 性能开销:分布式事务需要额外的协调、日志、锁机制。我见过一个项目,引入分布式事务后,接口响应时间从50ms飙到500ms。
- 调试困难:分布式事务出问题,日志散落在各个节点,排查起来像大海捞针。
1.3.2 典型场景
不是所有场景都需要分布式事务。我建议你按这个标准来判断:如果数据不一致会直接导致经济损失或用户体验严重受损,那就需要。
| 场景 | 说明 | 推荐方案 |
|---|---|---|
| 电商下单 | 订单、库存、账户三个服务必须一致 | TCC或Saga |
| 银行转账 | 扣款和入账必须原子操作 | 可靠消息+本地事务 |
| 积分兑换 | 扣积分和发券需要一致 | 最大努力通知 |
| 库存扣减 | 超卖会导致严重问题 | 本地消息表 |
你想想看,像用户修改头像这种场景,头像没更新成功,用户再点一次就行了,完全不需要分布式事务。但如果是扣钱,少一分钱用户都会跟你急。
好了,这一章我们聊了分布式事务为什么会出现,CAP和BASE理论怎么指导我们的设计,以及实际落地时会遇到哪些坑。下一章,我会带你深入两阶段提交(2PC)的实现细节,看看这个经典的分布式事务协议到底是怎么工作的。