谈一谈你对分布式事务的理解?
2 个回答
希望有人告诉你开心比对错更重要。梅拾璎### 分布式事务的理解 分布式事务是指在分布式系统中跨多个节点或系统执行的事务操作,以确保这些操作要么全部成功,要么全部失败,从而保证数据的一致性。下面详细介绍几种常见的分布式事务解决方案及其优缺点。 #### 1. 2PC(两阶段提交) 2PC 引入了一个协调者,分为两个阶段:prepare 阶段和 commit 阶段。 - **第一阶段(Prepare)**:协调者给各个业务系统发送指令,业务系统收到后开始执行子事务的具体操作,然后反馈执行结果(成功或失败),并同步阻塞等待协调者的第二阶段指令。协调者在发送指令后进入超时等待状态,等待各业务系统的反馈。 - **第二阶段(Commit/Rollback)**:协调者根据第一阶段的反馈决定是提交还是回滚。如果所有业务系统都反馈成功,协调者通知各业务系统提交事务;如果有任何一个业务系统反馈失败,或者超时未收到反馈,协调者通知各业务系统回滚事务。如果网络出现问题,协调者会一直重试发送回滚指令。 - **缺点**: 1. **单点问题**:协调者挂掉会导致所有子系统阻塞等待。 2. **数据不一致**:在第二阶段如果部分业务系统接收到 commit 指令,而另一部分未接收到,可能导致数据不一致。 3. **同步阻塞**:子系统在执行阶段同步阻塞等待协调者的指令,一旦网络断开,会一直阻塞。 #### 2. 3PC(三阶段提交) 3PC 分为三个阶段:canCommit、preCommit 和 doCommit。 - **第一阶段(canCommit)**:协调者向参与者发送 canCommit 指令,询问是否可以执行,如果满足条件,参与者返回 ACK。 - **第二阶段(preCommit)**:协调者向参与者发送 preCommit 指令,让参与者执行事务但不提交,参与者执行成功后返回 ACK。 - **第三阶段(doCommit/Abort)**:协调者收到所有参与者的 ACK 后,发送 doCommit 指令让参与者提交事务。如果有任何一个参与者在第二阶段反馈失败,协调者发送 Abort 指令让参与者回滚。 - **与 2PC 的区别**: 1. 3PC 是非阻塞协议,参与者引入了超时机制。如果在第一阶段或第二阶段等待协调者指令超时,会自动回滚;第三阶段等待超时会自动提交。 2. 3PC 在第三阶段一定是提交事务,而 2PC 在协调者挂掉时无法确定事务状态。 - **问题**: 1. 第三阶段如果发送 abort 回滚指令,但部分参与者因网络原因未收到,超时后会自动提交事务,可能导致数据不一致。 #### 3. TCC(Try-Confirm-Cancel) TCC 分为 Try、Confirm 和 Cancel 三个阶段。 - **Try**:预留资源阶段,事务管理器发送 Try 指令,各业务系统预留执行操作所需的资源(如冻结库存)。 - **Confirm**:确认阶段,事务管理器发送 Confirm 指令,各业务系统执行实际的事务操作。 - **Cancel**:撤销阶段,如果任何一个业务系统在 Confirm 阶段失败,事务管理器发送 Cancel 指令,各业务系统回滚预留的资源。 - **缺点**: 1. **侵入性强**:每个业务系统需要实现 Cancel 对应的回滚逻辑代码。 2. **重试机制**:如果 Cancel 或 Confirm 一直失败,会不断重试,直到成功。 #### 4. 本地消息表法 上游服务将操作记录到本地消息表,并将操作记录封装成 Kafka 消息发送到消息队列。下游系统消费消息后通知上游服务,上游服务更新本地消息表状态。上游服务定时扫描本地消息表,重新发送未通知成功的操作记录。 - **优点**:保证消息的可靠性和最终一致性。 #### 5. 可靠消息最终一致性方案 RocketMQ 支持分布式事务,使用 Half topic 队列保存 prepare 消息,使用 Operation Topic 队列保存 commit 和 rollback 消息。 - **流程**: 1. 上游系统发送 prepare 消息到 RocketMQ。 2. prepare 消息成功后,上游系统执行本地事务。 3. 上游系统本地事务成功后发送 commit 消息到 RocketMQ,失败则发送 rollback 消息。 4. 如果 prepare 消息超时未收到 commit 或 rollback 指令,RocketMQ 查询上游系统的事务状态并处理。 #### 6. 最大努力通知方案 业务系统 A 执行本地事务完成后,发送消息到 MQ。专门的消费服务消费 MQ 的消息,记录消费情况,并不断调用系统 B 的接口,直到系统 B 执行成功。 ### 总结 分布式事务有多种解决方案,每种方案都有其优缺点和适用场景。选择合适的方案需要根据具体的业务需求、系统架构和性能要求来决定。了解这些方案及其原理,有助于在实际项目中设计和实现高效可靠的分布式事务。编辑于 2023-05-01 04:59 •IP属地 北京举报评论收藏
人一旦不害怕失去,态度就会变得随意,随你意,你随意。高澜分布式事务是在分布式系统中涉及到多个服务或组件的事务处理。由于每个服务或组件可能运行在不同的节点上,确保数据的一致性和事务的原子性变得复杂。分布式事务主要面临以下几个挑战:原子性、一致性、隔离性和持久性(ACID),以及一致性、可用性和分区容忍性(CAP)等理论的约束。 #### 1. ACID 特性 - **原子性(Atomicity)**:事务要么完全执行,要么完全不执行。 - **一致性(Consistency)**:事务执行后,数据库从一个一致性状态转换到另一个一致性状态。 - **隔离性(Isolation)**:事务的执行不受其他事务的干扰。 - **持久性(Durability)**:事务一旦提交,结果就会永久保存。 #### 2. CAP 定理 CAP 定理指出,在一个分布式系统中,最多只能同时满足以下三个属性中的两个: - **一致性(Consistency)**:所有节点在同一时刻具有相同的数据。 - **可用性(Availability)**:每个请求都能收到一个非错误的响应,但不保证数据是最新的。 - **分区容忍性(Partition tolerance)**:系统在遇到任意网络分区故障时仍能够继续运作。 #### 3. BASE 理论 BASE 理论是对 CAP 定理的一种权衡,强调可用性和最终一致性: - **基本可用(Basically Available)**:系统在出现故障时,允许部分功能丧失。 - **软状态(Soft state)**:系统状态可以在一段时间内不一致。 - **最终一致性(Eventually consistent)**:系统经过一定时间后,最终能达到一致性状态。 ### 分布式事务的实现方式 #### 1. 两阶段提交协议(2PC) 两阶段提交协议分为两个阶段: - **准备阶段(Prepare phase)**:协调者向所有参与者发送准备请求,参与者准备好后向协调者返回准备就绪。 - **提交阶段(Commit phase)**:协调者根据所有参与者的反馈决定提交或回滚事务,并通知所有参与者。 **优点**:实现了事务的原子性。 **缺点**:存在单点故障,协调者故障会导致参与者长时间等待;网络分区可能导致一致性问题。 #### 2. 三阶段提交协议(3PC) 在两阶段提交的基础上增加了超时机制,分为三个阶段: - **准备阶段**:与 2PC 一致。 - **预提交阶段**:协调者向参与者发送预提交请求,参与者返回预提交响应。 - **提交阶段**:协调者根据参与者的预提交响应决定提交或回滚事务。 **优点**:解决了 2PC 的单点故障问题。 **缺点**:仍然存在一致性问题,复杂度较高。 #### 3. 补偿事务(TCC) TCC 模式将事务拆分为三个步骤:Try、Confirm 和 Cancel。 - **Try**:预留资源。 - **Confirm**:确认并执行实际操作。 - **Cancel**:回滚操作。 **优点**:灵活性高,适用于需要长时间业务处理的场景。 **缺点**:实现复杂度高,需要业务代码支持。 #### 4. 消息队列事务 通过消息队列实现最终一致性,具体步骤如下: - 发送消息到消息队列。 - 消息队列将消息发送给消费者。 - 消费者处理消息并确认处理成功。 **优点**:提高了系统的可用性和扩展性。 **缺点**:需要保证消息的可靠性和顺序性,处理复杂。 ### 实例代码 #### 两阶段提交示例(伪代码) ```java public class TwoPhaseCommit { public static void main(String[] args) { Coordinator coordinator = new Coordinator(); List<Participant> participants = Arrays.asList(new Participant(), new Participant()); // 准备阶段 for (Participant participant : participants) { if (!participant.prepare()) { coordinator.rollback(participants); return; } } // 提交阶段 coordinator.commit(participants); } } class Coordinator { void commit(List<Participant> participants) { for (Participant participant : participants) { participant.commit(); } } void rollback(List<Participant> participants) { for (Participant participant : participants) { participant.rollback(); } } } class Participant { boolean prepare() { // 准备资源 return true; } void commit() { // 提交事务 } void rollback() { // 回滚事务 } } ``` ### 总结 分布式事务在分布式系统中具有挑战性,需要在一致性、可用性和性能之间进行权衡。常见的分布式事务实现方式包括两阶段提交、三阶段提交、补偿事务和消息队列事务。每种方法都有其优缺点,适用于不同的场景。在实际应用中,选择合适的分布式事务方案至关重要,以确保系统的稳定性和数据一致性。发布于 2023-01-06 18:38 •IP属地 黑龙江举报评论收藏
公众号进入网站体验更佳

