分布式系统学习10:分布式事务
分布式系统学习10:分布式事务
分布式事务是分布式系统中一个非常重要且复杂的话题。本文将从基础知识开始,深入探讨分布式事务的理论基础、各种实现方案及其优缺点,并结合具体应用场景进行分析。
1.为什么要用分布式事务
在单体架构中,业务操作(如下单)可以轻松地在一个数据库事务中完成。然而,随着业务的增长,系统逐渐演变为分布式系统,原有的单体架构被拆分为多个微服务。在这种情况下,一个业务操作可能需要跨多个服务进行,这就需要保证所有操作都能成功,以确保数据的一致性,因此分布式事务应运而生。
2.理论基础
分布式事务的理论基础主要围绕CAP理论展开,具体可以分为两类:
- 刚性事务(CP模式):遵循ACID原则,强调数据的强一致性。
- 柔性事务(AP+BASE模式):遵循BASE理论,允许一定时间内的数据不一致性,但要求最终达到一致性。
BASE理论
- 基本可用(Basically Available):系统在出现未知故障时,仍然能够提供服务。
- 软状态(Soft State):允许系统存在中间状态,即不同副本的数据可以暂时不一致。
- 最终一致性(Eventually Consistent):虽然存在软状态,但系统最终会达到数据一致性。
3.刚性事务(CP模式)
刚性事务的核心是XA协议,它通过事务管理器(Transaction Manager)和本地资源管理器(Resource Manager)来实现分布式事务的协调。常见的实现方式包括两阶段提交(2PC)和三阶段提交(3PC)。
3.1 两阶段提交(2PC)
2PC通过协调者(coordinator)和参与者(participant)来统一掌控事务操作。过程分为两个阶段:
- 准备阶段:协调者向所有参与者发送REQUEST-TO-PREPARE消息,参与者回复PREPARE或NO。
- 提交阶段:如果所有参与者都回复PREPARE,协调者发送COMMIT消息;否则发送ABORT消息。
缺点:
- 网络抖动可能导致数据不一致。
- 超时会导致同步阻塞。
- 单点故障风险高。
3.2 三阶段提交(3PC)
3PC在2PC的基础上增加了准备阶段,并引入超时机制。过程分为三个阶段:
- CanCommit:检查是否可以执行事务提交。
- PreCommit:检查是否可以进行事务预提交。
- DoCommit:正式提交事务。
尽管3PC对2PC进行了优化,但两者在实际应用中都存在较多限制,因此很少使用。
4.柔性事务(AP+BASE模式)
柔性事务允许数据在一定时间内存在不一致性,但要求最终达到一致性。常见的实现方案包括TCC、Saga、本地消息表、MQ事务方案和最大努力通知。
4.1 TCC补偿事务
TCC(Try Confirm Cancel)是一种应用层面的补偿事务,通过三个步骤实现:
- Try阶段:预留业务资源。
- Confirm阶段:执行业务逻辑,需要满足幂等性。
- Cancel阶段:释放预留资源,需要满足幂等性。
4.2 Saga事务
Saga事务通过一系列本地事务实现分布式事务,每个本地事务更新数据库后会触发下一个本地事务。Saga有两种实现方式:
- 基于事件的方式:类似于舞蹈编排,各个服务按照预设顺序执行。
- 基于命令的方式:类似于乐队指挥,由协调中心统一调度。
4.3 本地消息表
本地消息表方案将分布式事务拆分为本地事务处理,通过轮询消息表和MQ实现异步解耦。优点是方案轻量,但与业务强耦合。
4.4 MQ消息事务
MQ消息事务是对本地消息表的封装,将消息存储在MQ内部。通过两次网络请求(half消息和commit/rollback消息)实现事务的最终一致性。
4.5 最大努力通知
最大努力通知是对MQ事务的进一步优化,通过增加消息校对接口,确保事务接收方可以主动获取操作结果。适用于业务通知类型的场景。
5. Seata框架
Seata是一个开源的分布式事务解决方案,提供了多种事务模式(AT、TCC、SAGA、XA),可以简化分布式事务的实现。Seata的核心组件包括:
- TC (Transaction Coordinator) - 事务协调者:维护全局和分支事务的状态。
- TM (Transaction Manager) - 事务管理器:定义全局事务的范围。
- RM (Resource Manager) - 资源管理器:管理分支事务处理的资源。