0%

分布式事务

1. 基础原理

1.1. CAP理论

1.2. BASE理论

2. Seata框架

2.1. 基本架构和解决方案

img

img

2.2. 配置

**config文件:**seata是微服务架构中的一个服务,可能集群化部署,所以也需要一个服务中心和配置中心,对各个机器的配置文件统一管理。

img

img

**数据库表:**配置文件中有数据库的配置,seata的功能需要依赖数据库,比如redis或者MySQL,数据库中主要有全局事务表以及分支事务表

引入微服务依赖:

  1. 注意事务组和集群名称的概念
  2. nacos 服务名称的组成 namespace+group+serviceName+cluster

img

3. 解决方案

3.1. XA模式

XA又叫两阶段提交,是一种分布式事务的标准,基于数据库本身的事务

img

3.1.1. 流程

RM 一阶段的工作:
- 注册分支事务到TC
- 执行分支业务sql但不提交
- 报告执行状态到TC
TC 二阶段的工作:
TC 检测各分支事务执行状态
a. 如果都成功,通知所有RM提交事务
b. 如果有失败,通知所有RM回滚事务
RM 二阶段的工作:
接收TC 指令,提交或回滚事务

3.1.2. 优缺点

优点:强一致性、侵入性低

缺点:长时间不提交事务,如果涉及到了锁,会影响性能

3.1.3. 实现

基于代理模式实现

img

3.2. AT 模式

解决XA的长时间阻塞,思路是 提交+快照恢复

img

3.2.1. 流程

img

RM 第一阶段 注册事务到TC,执行并提交事务,生成快照

TC 第二阶段,检查事务状态,决定提交或回滚

RM 第二阶段,读取快照恢复数据,或者删除快照

3.2.2. 优缺点

优点:不会长时间阻塞

缺点:最终一致性 会有脏写问题造成丢失更新

TC维护一个锁表,使用全局锁完成写隔离,锁粒度比DB锁小,假如其他事务没有在Seata维护,要修改该行数据其他字段,是可以进行的

如果非seata事务和seata事务对同一个字段进行修改也没问题,因为快照是在更新前后加的,如果检查时发现更新后快照与当前数据库状态不一致,会报警,人工介入

3.2.3. 实现

包含四张表,RM维护undolog表,TC维护全局锁表,以及全局事务表、分支事务表

3.3. TCC模式

利用资源预留,不需要加锁,追求性能

三阶段:try,cancal,confirm

3.3.1. 流程

img

3.3.2. 优缺点

优点:不依赖于事务型数据库,性能高

缺点:侵入性强,最终一致性,confirm和cancal的幂等性

3.3.3. 实现

空回滚问题

img

业务悬挂问题

img

需要加一个表:冻结表

img

防止空回滚:在回滚前判断根据事务id在冻结表中查询,看看有没有该记录,如果没有就插入一条记录(xid,状态为cancel)

避免业务悬挂:try的时候检查是否存在该事务

只对扣减金额做了TCC,另外两个下单以及扣减库存,用的是AT模式

3.4. Saga模式

用来解决长事务,第一阶段是提交事务,第二个阶段如果失败就执行补偿业务

有隔离性安全问题风险

img

3.5. 四种方案对比

img

最终一致指的是可能事务持续时间不能确定

3.6. 高可用

3.6.1. 高可用集群结构

img

nacos支持热更新,当SH挂了,手动改为HZ即可

3.7. 其他分布式事务实现方式

3.7.1. 3PC

另外提一句,分布式事务的实现除了2PC外,还有3PC。与2PC相比,3PC主要多了事务超时、多次重复尝试,以及提交check的功能。但因为确认步骤过多,很多业务的互斥排队时间会很长,所以3PC的事务失败率要比2PC高很多。

为了减少3PC因资源锁定等待超时导致的重复工作,3PC做了预操作,整体流程分成三个阶段:

  • CanCommit阶段:为了减少因等待锁定数据导致的超时情况,提高事务成功率,事务协调器会发送消息确认资源管理器的资源锁定情况,以及所有子事务的数据库锁定数据的情况。
  • PreCommit阶段:执行2PC的Prepare阶段;
  • DoCommit阶段:执行2PC的Commit阶段。

总体来说,3PC步骤过多,过程比较复杂,整体执行也更加缓慢,所以在分布式生产环境中很少用到它,这里我就不再过多展开了。

3.7.2. 本地事务表

3.7.3. RocketMQ 半消息