码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 分布式事务(四)———SAGA 解决方案


    分布式事务(四)———SAGA 解决方案

      • 简介
      • 一、核心原理
      • 二、恢复策略
      • 三、实现方式
        • 1.基于事件的方式
        • 2.基于状态机的方式
    • 系列文章

    该系列参考:
    https://www.jianshu.com/p/962271bbf4ea
    https://blog.csdn.net/a745233700/article/details/122402303
    https://cloud.tencent.com/developer/article/2048776
    https://icyfenix.cn/

    简介

    SAGA 事务模式的历史十分悠久,还早于分布式事务概念的提出。它源于 1987 年普林斯顿大学的 Hector Garcia-Molina 和 Kenneth Salem 在 ACM 发表的一篇论文《SAGAS》(这就是论文的全名)。文中提出了一种提升“长时间事务”(Long Lived Transaction)运作效率的方法,大致思路是把一个大事务分解为可以交错运行的一系列子事务集合。原本 SAGA 的目的是避免大事务长时间锁定数据库的资源,后来才发展成将一个分布式环境中的大事务分解为一系列本地事务的设计模式

    一、核心原理

    在这里插入图片描述

    • 大事务拆分若干个小事务,将整个分布式事务 T 分解为 n 个子事务,命名为 T1,T2,…,Ti,…,Tn。每个子事务都应该是或者能被视为是原子行为。如果分布式事务能够正常提交,其对数据的影响(最终一致性)应与连续按顺序成功提交 Ti等价。
    • 为每一个子事务设计对应的补偿动作,命名为 C1,C2,…,Ci,…,Cn。Ti与 Ci必须满足以下条件:
      • Ti与 Ci都具备幂等性。
      • Ti与 Ci满足交换律(Commutative),即先执行 Ti还是先执行 Ci,其效果都是一样的。
      • Ci必须能成功提交,即不考虑 Ci本身提交失败被回滚的情形,如出现就必须持续重试直至成功,或者要人工介入。

    特点:补偿事务、最终一致性、不保证隔离性

    二、恢复策略

    如果 T1到 Tn均成功提交,那事务顺利完成,否则,要采取以下两种恢复策略之一:

    • 正向恢复(Forward Recovery):如果 Ti事务提交失败,则一直对 Ti进行重试,直至成功为止(最大努力交付)。这种恢复方式不需要补偿,适用于事务最终都要成功的场景,譬如在别人的银行账号中扣了款,就一定要给别人发货。正向恢复的执行模式为:T1,T2,…,Ti(失败),Ti(重试)…,Ti+1,…,Tn。
    • 反向恢复(Backward Recovery):如果 Ti事务提交失败,则一直执行 Ci对 Ti进行补偿,直至成功为止(最大努力交付)。这里要求 Ci必须(在持续重试后)执行成功。反向恢复的执行模式为:T1,T2,…,Ti(失败),Ci(补偿),…,C2,C1。

    从这里我们可以知道为什么SAGA一定要满足的三个条件了:

    • Ti与 Ci都具备幂等性:正向恢复下Ti有重试机制,反向恢复下Ci有重试机制
    • Ti与Ci交换律:Ci是Ti失败的补偿方案,假设Ti先执行(库存-10),Ci后执行补偿回滚(库存+10),假设因网络问题Ci先执行,Ti后执行,结果也要保持一致
    • Ci必须成功:这个很好理解,补偿方案如果不成功那就导致了数据一致性问题

    由于Saga事务不保证隔离性,所以补偿方案需要注意,并不是任何场景都能补偿的。比如:B给A转账100,A余额+100,B余额-100,本地事务提交成功了,分布式事务失败了需要回滚,而在回滚前A已经把余额全消费掉了,这时候肯定已经没办法进行补偿了。 (极端场景)

    三、实现方式

    1.基于事件的方式

    在基于事件的方式中,第一个服务执行完本地事务之后,会产生一个事件。其它服务会监听这个事件,触发该服务本地事务的执行,并产生新的事件。

    假设一个完整的订单流程包含了如下几个服务:

    • Order Service:订单服务
    • Payment Service:支付服务
    • Stock Service:库存服务
    • Delivery Service:物流服务

    采用基于事件的saga模式的订单处理流程如下:

    1. 订单服务创建一笔新订单,将订单状态设置为"待处理",产生事件ORDER_CREATED_EVENT。
    2. 支付服务监听ORDER_CREATED_EVENT,完成扣款并产生事件BILLED_ORDER_EVENT。
    3. 库存服务监听BILLED_ORDER_EVENT,完成库存扣减和备货,产生事件ORDER_PREPARED_EVENT。
    4. 物流服务监听ORDER_PREPARED_EVENT,完成商品配送,产生事件ORDER_DELIVERED_EVENT。
    5. 订单服务监听ORDER_DELIVERED_EVENT,将订单状态更新为"完成"。

    该模式下分布式事务的回滚:

    每个需要回滚的服务都需要提供补偿操作的事件监听

    假设库存服务由于库存不足没能正确完成备货,我们可以按照下面的流程来回滚整个Saga事务:

    1. 库存服务产生事件PRODUCT_OUT_OF_STOCK_EVENT。
    2. 订单服务和支付服务都会监听该事件并做出响应:
      1. 支付服务完成退款。
      2. 订单服务将订单状态设置为"失败"。

    该模式需要注意的点:

    1. 从事务入口就需要生成唯一的事务ID全局传递
    2. 每个服务都需要准备事务处理Log表,防止服务宕机事件丢失
    3. 要保证消息的可靠性,确保成功发送和成功消费 (类似本地消息事务表)
    4. 如业务允许完全可以不需要回滚监听,直接正向重试恢复
    5. 监听接口都需要保证幂等性
    6. 需要防止形成环形监听,也就是两个业务方相互监听对方事件

    2.基于状态机的方式

    DEMO详情见 : https://github.com/seata/seata-samples
    Seata文档详情见: https://seata.io/zh-cn/docs/overview/what-is-seata.html

    引入一个协调中心,所有需要参与事务的服务都与之交互,事务的流程状态都由协调中心控制
    这里直接可以看阿里的Seata Saga模式

    系列文章

    • 分布式事务(一)———CAP、BASE理论
    • 分布式事务(二)———2PC/3PC(强一致性)解决方案
    • 分布式事务(三)———TCC 解决方案
    • 分布式事务(四)———SAGA 解决方案
    • 分布式事务(五)———可靠消息队列解决方案
  • 相关阅读:
    Unity 编辑器资源导入处理函数 OnPostprocessTexture :深入解析与实用案例
    输电线路故障数据集(单相接地故障、两相接地故障、两相间短路故障、三相间短路故障)
    【Java】封装、继承、多态
    二、.Net Core搭建Ocelot
    Ubuntu下Python3与Python2相互切换
    代码随想录训练营二刷第四十一天 | 509. 斐波那契数 70. 爬楼梯 746. 使用最小花费爬楼梯
    Apache Seata如何解决TCC 模式的幂等、悬挂和空回滚问题
    Spring Security 自定义资源服务器实践
    【自学记录】深度学习入门——基于Python的理论与实现(第4章 神经网络的学习)
    Spring原理:PostProcessor与AOP原理
  • 原文地址:https://blog.csdn.net/weixin_44102992/article/details/126593341
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号