|
@@ -1,13 +1,23 @@
|
|
|
## 了解分布式事务吗?
|
|
|
|
|
|
+> **分布式系统中一次操作由多个服务协同完成,这种一次事务操作涉及多个系统通过网络协同完成的过程称为分布式事务。**
|
|
|
+
|
|
|
分布式事务一般满足CAP原则
|
|
|
|
|
|
CAP 是 Consistency、Availability、Partition tolerance 三个单词的缩写,分别表示一致性、可用性、分区容忍性。
|
|
|
|
|
|
* 一个分布式系统最多同时满足一致性、可用性、分区容错性三项中的两项。
|
|
|
-
|
|
|
* 一般来讲都会选择保证A和P,舍弃一致性,保证最终一致性。
|
|
|
|
|
|
+### BASE理论
|
|
|
+BASE是Basically Available(基本可用)、Soft state(软状态)和Eventually consistent(最终一致性)的缩写。
|
|
|
+
|
|
|
+在分布式系统中,CAP理论是指导思维,而BASE理论是CAP理论中AP的延伸,是对 CAP 中的一致性和可用性进行一个权衡的结果,核心思想是:即使无法做到强一致性,但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性。
|
|
|
+
|
|
|
+* 基本可用(Basically Available):指分布式系统在出现故障的时候,允许损失部分可用性,保证核心可用。
|
|
|
+* 柔性状态(Soft state):指允许系统存在中间状态,并认为该中间状态不会影响系统整体可用性。比如,允许不同节点间副本同步的延时就是柔性状态的体现。
|
|
|
+* 最终一致性(Eventually consistent):指系统中的所有副本经过一定时间后,最终能够达到一致的状态。因此,最终一致性的本质是需要系统保证最终数据能够达到一致,而不需要实时保证系统数据的强一致性。
|
|
|
+
|
|
|
### 1、2PC/XA方案
|
|
|
|
|
|
所谓的 XA 方案,即:两阶段提交,有一个事务管理器的概念,负责协调多个数据库(资源管理器)的事务,事务管理器先问问各个数据库你准备好了吗?如果每个数据库都回复 ok,那么就正式提交事务,在各个数据库上执行操作;如果任何其中一个数据库回答不 ok,那么就回滚事务。
|
|
@@ -28,13 +38,22 @@ TCC 的全称是:`Try`、`Confirm`、`Cancel`。
|
|
|
|
|
|
### 3、可靠消息最终一致性方案
|
|
|
|
|
|
-基于 MQ 来实现事务。比如阿里的 RocketMQ 就支持消息事务。大概的意思就是:
|
|
|
+或者基于本地消息表
|
|
|
|
|
|
-1. A 系统先发送一个 prepared 消息到 MQ,如果这个 prepared 消息发送失败那么就直接取消操作别执行了;
|
|
|
-2. 如果这个消息发送成功过了,那么接着执行本地事务,如果成功就告诉 MQ 发送确认消息,如果失败就告诉 MQ 回滚消息;
|
|
|
-3. 如果发送了确认消息,那么此时 B 系统会接收到确认消息,然后执行本地的事务;
|
|
|
-4. mq 会自动定时轮询所有 prepared 消息回调你的接口,问你,这个消息是不是本地事务处理失败了,所有没发送确认的消息,是继续重试还是回滚?一般来说这里你就可以查下数据库看之前本地事务是否执行,如果回滚了,那么这里也回滚吧。这个就是避免可能本地事务执行成功了,而确认消息却发送失败了。
|
|
|
-5. 这个方案里,要是系统 B 的事务失败了咋办?重试咯,自动不断重试直到成功,如果实在是不行,要么就是针对重要的资金类业务进行回滚,比如 B 系统本地回滚后,想办法通知系统 A 也回滚;或者是发送报警由人工来手工回滚和补偿。
|
|
|
+![image.png](assets/955fdfb94c234e32939c76954fd28a56tplv-k3u1fbpfcp-zoom-in-crop-mark1512000.awebp)
|
|
|
+
|
|
|
+实现流程:
|
|
|
+ 1. 事务发起方发送Half事务消息
|
|
|
+ 2. RocketMq回复Half发送成功
|
|
|
+ 3. 事务发起方执行本地事务
|
|
|
+ 4. 事务发起方执行本地事务成功,发送commit到RocketMq,mq投递消息到事务参与方;
|
|
|
+ 事务发起方执行本地事务失败,发送rollback到RocketMq,mq删除消息。
|
|
|
+ 5. 当RocketMq一定时间内未收到来自事务发起方的确认信息,会对事务发起方进行事务回查。
|
|
|
+ 6. 事务发起方查询本地事务状态。
|
|
|
+ 7. 事务发起方根据查询到的事务状态发送commint/rollback到RocketMq,继续走8或9。
|
|
|
+ 8. 当RocketMq发起commit后,收到失败或一定时间未收到成功ack,则会发起重试。
|
|
|
+
|
|
|
+> **这个方案里,要是系统 B 的事务失败了咋办?重试咯,自动不断重试直到成功,如果实在是不行,要么就是针对重要的资金类业务进行回滚,比如 B 系统本地回滚后,想办法通知系统 A 也回滚;或者是发送报警由人工来手工回滚和补偿。**
|
|
|
|
|
|
### 4、最大努力通知方案
|
|
|
|
|
@@ -42,6 +61,12 @@ TCC 的全称是:`Try`、`Confirm`、`Cancel`。
|
|
|
2. 这里会有个专门消费 MQ 的最大努力通知服务,这个服务会消费 MQ 然后写入数据库中记录下来,或者是放入个内存队列也可以,接着调用系统 B 的接口;
|
|
|
3. 要是系统 B 执行成功就 ok 了;要是系统 B 执行失败了,那么最大努力通知服务就定时尝试重新调用系统 B,反复 N 次,最后还是不行就放弃。
|
|
|
|
|
|
+### 5、XA和TCC的区别
|
|
|
+
|
|
|
+XA是把所有数据执行成功的通知发送给协调器(第一阶段),协调器在执行commit(第二阶段),并且数据源还要保证XA协议
|
|
|
+
|
|
|
+TCC是第一阶段就把事务commit了(try接口),TCC的第二阶段是一个确认(Confirm)的阶段,也就是说只需要调用各个子系统里的confirm逻辑,所以在执行confirm逻辑的时候,并不会持有数据库的锁,所以不会产生性能问题。
|
|
|
+
|
|
|
## 如何设计一个高可用,高性能的系统?
|
|
|
|
|
|
![高性能思维导图](assets/202308021211012.jpeg)
|