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就得继续响应请求,但数据可能不一致(牺牲一致性)。

我个人习惯: 在实际架构设计中,P是必须选的。因为网络分区一定会发生,只是时间问题。所以真正的选择是在CP和AP之间做取舍。

我在项目中遇到过这样的场景:配置中心这种系统,我选CP,宁可暂时不可用,也不能让配置乱掉。但像用户点赞这种场景,我选AP,少几个赞无所谓,系统不能挂。

1.2.2 BASE理论

BASE理论是CAP的实践延伸。它说:既然强一致性做不到,那就退而求其次,追求最终一致性

BASE包含三层意思:

  • BA(Basically Available)基本可用:系统允许部分功能降级,比如双十一时,查询历史订单可以延迟几秒,但不能查不到。
  • S(Soft State)软状态:允许系统存在中间状态,数据同步过程中,不同节点的数据可以不一致。
  • E(Eventually Consistent)最终一致性:经过一段时间后,所有节点的数据最终会达成一致。

说白了,BASE就是告诉我们要务实。强一致性太贵了,我们付不起那个性能代价。我曾经在一个金融项目中,硬要用两阶段提交保证强一致,结果TPS直接掉到两位数,被业务方骂惨了。后来改成最终一致性加补偿机制,性能上去了,数据也没出过问题。

避坑指南: 我曾经以为BASE就是"随便搞搞,反正最终会一致"。结果线上数据对不上,查了三天才发现是补偿逻辑没写好。最终一致性不是"不处理",而是"延迟处理但必须处理"。

1.3 分布式事务的挑战与场景

1.3.1 核心挑战

做分布式事务,说白了就是在跟这几个问题死磕:

  1. 网络不可靠:请求可能丢、可能重、可能延迟。你发一个提交指令,对方收到了吗?不知道。你发一个回滚指令,对方执行了吗?也不知道。
  2. 节点故障:服务可能突然挂了,数据库可能宕机了。事务进行到一半,协调者挂了怎么办?参与者挂了怎么办?
  3. 数据一致性:多个服务各自维护自己的数据,怎么保证它们要么一起变,要么都不变?
  4. 性能开销:分布式事务需要额外的协调、日志、锁机制。我见过一个项目,引入分布式事务后,接口响应时间从50ms飙到500ms。
  5. 调试困难:分布式事务出问题,日志散落在各个节点,排查起来像大海捞针。
我的经验: 分布式事务最大的挑战不是技术实现,而是"你永远不知道下一秒哪个节点会出什么幺蛾子"。所以设计时一定要考虑幂等、重试、补偿这些兜底机制。

1.3.2 典型场景

不是所有场景都需要分布式事务。我建议你按这个标准来判断:如果数据不一致会直接导致经济损失或用户体验严重受损,那就需要

场景 说明 推荐方案
电商下单 订单、库存、账户三个服务必须一致 TCC或Saga
银行转账 扣款和入账必须原子操作 可靠消息+本地事务
积分兑换 扣积分和发券需要一致 最大努力通知
库存扣减 超卖会导致严重问题 本地消息表

你想想看,像用户修改头像这种场景,头像没更新成功,用户再点一次就行了,完全不需要分布式事务。但如果是扣钱,少一分钱用户都会跟你急。

我建议: 能用本地事务解决的,绝不用分布式事务。分布式事务是最后的手段,不是第一选择。先看看能不能通过业务设计规避掉,比如把相关操作放到同一个服务里。

好了,这一章我们聊了分布式事务为什么会出现,CAP和BASE理论怎么指导我们的设计,以及实际落地时会遇到哪些坑。下一章,我会带你深入两阶段提交(2PC)的实现细节,看看这个经典的分布式事务协议到底是怎么工作的。