2025/12/31 13:27:26
网站建设
项目流程
举重运动员 做网站,品牌推广和市场推广的区别,国内做免费的视频网站有哪些,移动互联网app开发微服务架构下的分布式事务解决方案
第一篇内容#xff1a;
什么是分布式事务#xff08;定义、产生背景、核心难点#xff09;什么时候使用#xff08;跨库、跨服务场景、电商案例#xff09;理论基石#xff08;CAP 权衡、CP vs AP#xff09;强一致性方案#xff0…微服务架构下的分布式事务解决方案第一篇内容什么是分布式事务定义、产生背景、核心难点什么时候使用跨库、跨服务场景、电商案例理论基石CAP 权衡、CP vs AP强一致性方案2PC 详解与缺陷、3PC 的改进与局限架构视角下的分布式事务一核心理论与强一致性方案第二篇内容TCC 补偿型事务Try-Confirm-Cancel 详解、三大异常处理可靠消息最终一致性基于 MQ 本地消息表方案Saga 长事务模式编排式 vs 协同式、ACD 模型全文总结与选型建议TCC - 补偿型事务TCCTCC是一种位于应用层Business Layer的分布式事务解决方案。与 2PC/XA 依赖数据库层面的锁不同TCC 将资源管理的粒度上移到业务逻辑中通过业务代码来实现资源的预留、确认和释放。它本质上是一种柔性事务Flexible Transaction遵循BASE 理论追求最终一致性。可以将其视为**“应用层的两阶段提交”**。TCC 执行流程TCC 模式将一个业务操作拆分为三个接口Try、Confirm、Cancel。三阶段详解Try 阶段业务检查 资源预留核心逻辑完成所有的业务一致性检查Business Check并预留必须的业务资源Reserve Resources。特点只做“准”操作不做“实”操作。示例转账场景中不是直接扣钱而是检查余额是否充足并将转账金额从“可用余额”移动到“冻结字段”。Confirm 阶段业务确认核心逻辑真正执行业务不做任何业务检查Try 阶段已做过。只使用 Try 阶段预留的资源。特点满足幂等性。如果 Try 成功Confirm 必须成功。如果执行失败事务管理器会进行重试直到成功。Cancel 阶段业务取消核心逻辑释放 Try 阶段预留的业务资源。特点满足幂等性。这是“反向操作”或“补偿操作”。TCC 的三大关键技术挑战在分布式网络环境下TCC 必须处理三种棘手的异常情况这要求业务代码具备极高的鲁棒性。1. 幂等性场景无论是 Confirm 还是 Cancel都可能因为网络超时Packet Loss导致事务管理器重复发送请求。要求业务接口必须保证重复调用产生的结果是一样的。实现通常通过引入“事务记录表”或利用“状态机”判断如果该事务 ID 已经处理过则直接返回成功不重复扣款或回滚。2. 空回滚场景事务管理器调用 Service A 的Try请求但因为网络故障请求未到达Service A或者 Service A 还没处理完就抛错了。此时事务管理器判定 Try 失败触发全局回滚向 Service A 发送Cancel请求。问题Service A 根本没收到过Try却收到了Cancel。要求Cancel接口必须能识别这种情况允许“未 Try 先 Cancel”直接返回成功什么都不做。实现查询事务记录表如果没找到对应的 Try 记录说明是空回滚。3. 资源悬挂场景事务管理器调用Try发生严重的网络拥塞超时。事务管理器判定超时发出Cancel。Cancel先到达并执行成功处理了空回滚逻辑。随后迟到的Try请求终于到达了。问题如果执行了这个迟到的Try资源就被预留冻结了。但因为全局事务已经结束已回滚永远不会有Confirm或Cancel来释放这笔资源。这笔资源就被永久“悬挂”锁死了。要求Try方法执行前必须检查该事务 ID 是否已经执行过Cancel。如果已回滚拒绝执行Try。实现利用“防悬挂记录”或检查事务状态若发现已有 Cancel 记录则 Try 抛出异常或直接返回。TCC 的优缺点深度分析优点性能与灵活性高并发High ConcurrencyTCC 不使用数据库层面的全局排他锁Global Lock。锁的粒度在业务层如行记录的状态字段只会阻塞该条数据的特定状态变更不会阻塞整个表的访问。资源锁定时间短不占用数据库连接。细粒度控制可以针对不同的服务实现不同的补偿逻辑支持异构数据库。缺点高开发成本与代码侵入强代码侵入性Service 层的每个接口都必须改造。原本的一个 update 接口现在需要拆解为 Try、Confirm、Cancel 三个逻辑。业务逻辑与事务逻辑耦合严重。开发成本高昂 一个业务链路如果有 5 个服务就需要写 15 个接口方法。开发人员必须深刻理解 TCC 原理手动处理预留资源的逻辑如给数据库表加frozen_amount字段。复杂度极高必须完美处理上述的幂等、空回滚、悬挂三大异常否则会导致数据错乱或资金损失。这通常需要依赖成熟的 TCC 框架如 Seata TCC 模式, ByteTCC, Himly来辅助实现。可靠消息最终一致性可靠消息最终一致性可靠消息最终一致性是一种基于BASE 理论的分布式事务解决方案通常归类为AP可用性优先架构。它通过引入消息队列 (Message Queue, MQ)进行异步解耦将长事务拆分为本地事务和下游事务。其核心目标是保证只要上游服务生产者的本地事务提交成功下游服务消费者最终一定能收到消息并执行成功。该方案通常采用“本地消息表 (Transactional Outbox Pattern)”或“事务消息 (Transactional Messaging)”来实现。架构流程图 (基于本地消息表模式)此图展示了如何保证“本地事务执行”与“消息发送”的原子性以及下游如何保证最终成功。核心机制深度解析1. 上游原子性本地消息表这是解决“业务执行”与“发送MQ”非原子性问题的经典方案。问题背景先发 MQ 后写库库写失败了怎么办先写库后发 MQMQ 发失败了怎么办解决方案利用本地数据库的ACID 特性。在同一个本地事务中既写入业务数据如生成订单也写入一条消息记录状态待发送。结果业务数据和消息记录要么同时存在要么同时回滚。2. 消息投递可靠性保证即使消息落库了还需要保证投递到 MQ。轮询/投递 (Poller)一个独立的线程或定时任务不断扫描“待发送”的消息投递到 MQ。状态翻转投递成功后将本地消息状态更新为**“已发送”**。兜底机制如果更新状态失败或者 MQ 没收到定时任务下次还会扫描到这条消息进行重发这就要求下游必须幂等。3. 下游消费重试与死信下游服务可能因为网络抖动、数据库繁忙等原因暂时失败。ACK 机制 (Acknowledgement)只有业务逻辑完全执行成功后消费者才向 MQ 发送确认ACK。自动重试策略如果消费者抛出异常或超时未 ACKMQ 会根据策略如指数退避算法1s, 5s, 10s…重新投递消息。死信队列 (Dead Letter Queue, DLQ)当重试次数达到阈值如 16 次仍未成功MQ 将该消息移入 DLQ。这意味着发生了人工介入级别的故障如代码 Bug 或数据错误系统会自动告警由运维或开发手动处理。4. 关键防御幂等性设计 (Idempotency)由于网络的不确定性和 MQ 的重试机制消息被重复投递是必然发生的 (At-Least-Once Delivery)。下游必须保证重复消费不会导致业务错误。唯一键约束 (Unique Key)利用数据库的唯一索引如order_id或message_id防止插入重复记录。去重表 (Deduplication Table)专门建立一张表记录已处理的message_id。消费前先查表若存在则直接 ACK 并返回。状态机控制 (State Machine)UPDATE orders SET status PAID WHERE id 100 AND status UNPAID;利用UPDATE语句的行锁和条件判断CAS 乐观锁思想确保状态只能流转一次。方案优缺点总结优点解耦 (Decoupling)生产者不需要关心消费者是否在线发完消息即可结束。削峰填谷 (Load Leveling)能够承受高并发冲击。代码侵入性较低相比 TCC不需要拆分 Try/Confirm/Cancel主要逻辑集中在消息发送和消费端。缺点实时性较差依赖异步投递存在一定延迟。运维复杂度需要维护独立的消息服务、定时任务和消息表清理机制。不支持回滚一旦消息发出如果下游一直失败进入死信上游通常无法自动回滚只能通过“人工补偿”或生成“反向消息”来修正数据。Saga模式 - 长事务补偿Saga 模式Saga 模式是一种处理分布式系统中长运行事务Long-Running Transaction的解决方案。它放弃了传统 ACID 中强一致性和隔离性的要求转而采用BASE 理论。Saga 将一个全局的分布式事务拆分为一系列有序的本地事务 (Local Transaction)。每个本地事务更新数据库并发布事件触发下一个本地事务。核心逻辑包含两个部分正向操作 (Transaction, T)正常的业务逻辑执行。补偿操作 (Compensation, C)当某个步骤失败时用于撤销之前操作的逻辑。Saga 的两种主要实现模式编排式 (Orchestration)引入一个中心化的SEC (Saga Execution Coordinator)。协调器负责指挥“A 执行完告诉我我再通知 B如果 B 失败我通知 A 执行补偿”。特点可视化流畅状态机逻辑清晰便于排查问题。协同式 (Choreography)没有中心协调器服务之间通过事件 (Event)驱动。服务 A 完成后发消息服务 B 监听消息并执行。特点耦合度极低在业务流程混乱时难以追踪。编排式 (Orchestration)是目前更主流、更推荐的选择Saga 执行流程图 (基于编排器模式)下图展示了 Saga 在遇到故障时如何通过反向补偿来回滚事务。假设业务流程是扣减库存 (T1)-创建订单 (T2)-支付扣款 (T3)。场景T1, T2 成功但 T3 失败。流程详解正向执行依次执行 T1, T2。每个事务执行完立即提交本地数据库事务锁资源被释放。故障触发执行到 T3 时发生错误如余额不足。反向补偿Saga 协调器Orchestrator感知到 T3 失败开始按相反顺序调用已完成步骤的补偿操作。调用C2T2 的补偿将订单状态改为“已取消”或物理删除。调用C1T1 的补偿将扣减的库存加回去。最终状态数据库回滚到事务开始前的状态数据语义上的一致。核心特性与缺陷深度解析1. 缺失隔离性 - ACD 模型这是 Saga 与 TCC/XA 最大的区别也是其被诟病为“ACD”缺了 I - Isolation的原因。现象在 Saga 执行过程中例如 T1 刚提交T2 还没开始其他并发的业务请求可以看到T1 已经提交的数据。风险 - 脏读 (Dirty Read)如果 T1 扣了库存此时用户 B 查询到了有库存。但随后 Saga 触发了补偿 C1 把库存加回去了。用户 B 看到的就是一个中间状态的数据。对策业务设计上必须容忍“语义锁”或使用“冻结字段”策略或者在业务层面做隔离例如订单状态标记为“处理中”对用户不可见。2.补偿的复杂性“撤销”往往比“做”更难。逻辑难写发送邮件的 T 操作其 C 操作无法“撤回邮件”只能“发送一封更正邮件”。重试机制补偿操作C1本身也可能失败例如网络断了。Saga 框架必须保证补偿操作无限重试直到成功这就要求人工介入死信队列作为最后的兜底。3. 必须幂等由于网络环境的不稳定性Saga 协调器可能会重复触发正向操作T或补偿操作C。要求C1执行一次和执行 N 次效果必须完全一样例如库存 库存 1必须改为如果流水号不存在则库存1。总结Saga 是一种**“先提交后补偿”的模式。它牺牲了隔离性Isolation换取了长事务场景下的高并发与低延迟**因为没有长周期的数据库锁。适用于业务流程长、跨系统多、且允许短暂数据不一致的场景。全文总结与选型指南分布式事务是微服务架构中绕不开的挑战。从早期的数据库层面的2PC/XA到后来应用层面的TCC、Saga技术演进的核心逻辑始终是在“一致性 (Consistency)”与“可用性/性能 (Availability/Performance)”之间寻找平衡点。1. 技术演进脉络从刚性到柔性传统的2PC/3PC追求 ACID 的强一致性但因同步阻塞导致性能低下不适应互联网高并发场景。因此基于 BASE 理论的柔性事务TCC、MQ、Saga应运而生它们允许数据在短时间内不一致但保证最终一致。从数据库层到业务层事务管理的控制权逐渐从数据库DB Lock上移至业务代码Business Logic。虽然这增加了开发的复杂度如处理幂等、空回滚但也带来了极大的性能提升和灵活性。2. 核心选型在做架构决策时可以参考以下优先级首选策略避免分布式事务如果可以通过合理的微服务拆分领域模型调整或数据分片策略将操作限制在同一个数据库内利用本地事务解决那是最高效的。资金/核心业务强一致性 (Seata AT / 2PC)场景银行转账、企业内部 ERP、数据准确性要求极高的核心链路。理由必须保证数据时刻一致不能容忍中间状态且并发量通常可控。高并发互联网业务最终一致性 (MQ / TCC)场景 1 (高并发、解耦)电商下单后发货、积分发放、推送通知。推荐可靠消息最终一致性 (MQ)。实现解耦削峰填谷。场景 2 (强实时、细粒度控制)支付扣款、库存扣减需立即反馈结果。推荐TCC。虽然代码侵入大但能提供最高的性能和控制力。长链路复杂业务Saga 模式场景旅游预订机票酒店租车、跨境物流链。推荐Saga (编排式)。流程长、参与者多不需要强隔离性侧重于流程的可视化管理和补偿机制。