Saga 事务Saga 事务核心思想是将"长事务拆分为多个本地短事务",由 Saga 事务协调器协调,如果正常结束那就正常完成, 如果"某个步骤失败,则根据相反顺序一次调用补偿操作"。 Saga 事务基本协议如下:1、每个 Saga 事务由一系列幂等的有序子事务(sub-transaction) Ti 组成。 TCC事务补偿机制有一个预留(Try)动作,相当于先报存一个草稿,然后才提交;Saga事务没有预留动作,直接提交。 优点命令协调设计的优点如下:服务之间关系简单,避免服务之间的循环依赖关系,因为 Saga 协调器会调用 Saga 参与者,但参与者不会调用协调器。 由于 Saga 模型中没有 Prepare 阶段,因此事务间不能保证隔离性。
这里的重试本质上就是rollback的另一种形式,在saga里算是“forward recovery”。 借机又翻看了一下相关的文章,贴到了文末。 Saga vs TCC 1) Saga相比TCC的缺点是缺少预留动作,所以某些情况补偿的实现比较麻烦甚至无法撤销只能补救。不过没有预留动作也意味着不必担心资源释放的问题。 2) TCC最少通信次数为2n,Saga为n(n=sub-transaction的数量)。 3) 第三方服务没需要提供有Try接口。 总体感觉下来SAGA更适合微服务的多数场景。 试用 Saga 思想 解决这类问题当然可以直接引入一些已存在的saga框架,不过这里存在学习、部署等成本。如果只是小范围的解决问题,或许可以使用下面的形式。 可以把callback看作是saga事务参与方发送消息到"message broker"。而调用链的第一个节点就充当了saga的协调者。
协议介绍 Saga的组成: 每个Saga由一系列sub-transaction Ti 组成 每个Ti 都有对应的补偿动作Ci,补偿动作用于撤销Ti造成的结果 可以看到,和TCC相比,Saga没有“预留” Saga的执行顺序有两种: T1, T2, T3, ..., Tn T1, T2, ..., Tj, Cj,..., C2, C1,其中0 < j < n Saga定义了两种恢复策略: backward 而Saga则就直接发送邮件了(Ti),如果要撤销则得再发送一份邮件说明撤销(Ci),实现起来有一些麻烦。 TCC最少通信次数为2n,而Saga为n(n=sub-transaction的数量)。 有些第三方服务没有Try接口,TCC模式实现起来就比较tricky了,而Saga则很简单。 实现Saga的注意事项 对于服务来说,实现Saga有以下这些要求: Ti和Ci是幂等的。 Ci必须是能够成功的,如果无法成功则需要人工介入。
redux-saga负责调度管理 Saga来头不小(1W star不是浪得的),是某篇论文中提出的一种分布式事务机制,用来管理长期运行的业务进程 P.S.关于Saga背景的更多信息,请查看Background task与当前saga有关 fork所在的saga会等待forked task,只有在所有forked task都执行结束后,当前saga才会结束 fork的执行机制与all完全一致,包括cancel和 术语Saga指的是一系列操作的集合,是个运行时的抽象概念 redux-saga里的Saga形式上是generator,用来描述一组操作,而generator是个具体的静态概念 P.S.redux-saga 里所说的Saga大多数情况下指的都是generator形式的一组操作,而不是指redux-saga自身。 简单理解的话:在redux-saga里,Saga就是generator,Sagas就是多个generator Sagas有2种顺序组合方式: yield* saga() call(saga) 同样,直接
因此我们首先得学习Redux,中文官网地址:http://cn.redux.js.org/ 此时我们可以很好的在大型项目中管理我们的state了,但如果我们要异步获取数据、访问浏览器缓存等操作,就需要用到Redux-Saga 官网地址(英文):https://redux-saga.js.org/ 中文文档地址:https://redux-saga-in-chinese.js.org/ 我简单进行入门了一下,编写了一个redux-saga 的getting start demo https://gitee.com/VampireAchao/simple-redux-saga.git 注释都写得比较完善 运行方式: Setup cnpm
redux-saga redux-saga是一个用于管理redux应用异步操作的中间件,redux-saga通过创建sagas将所有异步操作逻辑收集在一个地方集中处理,可以用来代替redux-thunk https://github.com/redux-saga/redux-saga-beginner-tutorial.git 2.安装依赖 cd redux-saga-beginner-tutorial ; } 为了运行我们的 Saga,我们需要: 创建一个 Saga middleware 运行的 Sagas(目前我们只有一个 helloSaga) 将这个 Saga middleware 连接至 Redux /sagas 模块中的 Saga。然后使用 redux-saga 模块的 createSagaMiddleware 工厂函数来创建一个 Saga middleware。 (saga, …args) 动态地运行 saga。
saga中yield 后面的内容我们称呼它为Effect(redux-saga的任务单元),在Effects中我们可以进行启动其它saga,也可以处理一些副作用操作。 saga,takeLatest将取消上一次该saga的运行。 takeLatest第一个参数是*,即不再匹配某一个具体的action,而是匹配所有的action saga:监听到对应action,启动对应saga。 args:传递给saga函数的参数。 takeEvery(pattern, saga, ...args): 监听类型为pattern的action的派发,当监听到该类型的action,将执行第二个参数saga,且args将作为参数传递给saga 一般根saga文件都会使用该方法,即同时启动所有该项目所需要运行的saga任务。
Redux-saga 简介redux-saga 和 redux-thunk 一样, 是一个 Redux 中获取存储异步数据的中间件redux-saga 可以直接拦截 dispatch 派发的 action , 从而实现在执行 reducer 之前执行一些其它操作使用 Redux-saga安装 Redux-saganpm install redux-saga在创建 store 时应用 redux-saga createStore, applyMiddleware} from 'redux'/*注意点: 如果导入的是redux-thunk, 那么返回给我们的是一个中间件对象 如果导入的是redux-saga , 那么返回给我们的是一个用于创建中间件对象的方法* */import createSagaMiddleware from 'redux-saga'import reducer from '. /reducer';// 通过createSagaMiddleware方法创建saga中间件对象const sagaMiddleware = createSagaMiddleware();// 创建store
轻松实现 Saga 模式 翻译自 Making the Saga Pattern Work Without All the Headaches 。 Saga 模式是持久微服务执行的绝佳工具,但它会使维护变得困难。这是使其适用于您的系统的方法。 了解 Saga 模式 Saga 模式为这一旅程提供了一份路线图。该模式最早在 1987 年的一篇论文中讨论,通过使复杂过程能够彼此通信,将持久执行引入其中。中央控制器管理该服务通信和事务状态。 然而,使用 Saga 模式需要付出巨大的代价。原则上概念并没有问题,但一切取决于实现。开发人员传统上必须将该模式作为应用程序的一部分自己编写代码。 公司在使用 Saga 模式处理软件进程中的上下文切换方面已经朝着正确的方向迈出了一步。但是,通过将这些 Saga 模式抽象为一个独立的服务而不是应用层,公司可以走得更远。
1 Saga模式示例 1.1 Saga状态机工具 状态机设计组件:seata-saga-statemachine-designer 状态机在线画图工具:saga_designer 1.2 代码示例 github 上Seata-sample有完整的示例代码,Seata Saga模式中有此示例的完整介绍和分析。 3.1 Saga状态机引擎架构 注:此图来自seata官网的博客。 从代码的角度来看,Saga执行过程如下: 3.3 分布式事务的时序图 从时序图上可以看到,Saga模式和AT、TCC模式有较大的差异: Saga模式下TM、RM均由开启事务的微服务承担,AT、TCC Saga模式由一个状态机实现,其实现过程主要包括:路由到正确的state + 执行state。
最后好像也只好选择saga方案,另外有了servicecomb-saga后,spring-boot应用要使用分布式事务还是挺容易的。 servicecomb-saga的架构 servicecomb-saga的架构可直接参考其官方文档,写得还是比较详细的。 概览 Pack中包含两个组件,即 alpha 和 omega。 $ mysql mysql> create database saga default character set utf8; mysql> GRANT ALL PRIVILEGES ON saga. /target/saga/alpha-server-0.3.0-SNAPSHOT-exec.jar 配置Omega 按照servicecomb-saga的架构,所有支持分布式事务的spring-boot 引入Saga的依赖 应用的pom.xml配置文件中引入servicecomb-saga的依赖 <dependency> <groupId>org.apache.servicecomb.saga
本文要讲的就是Redux-Saga,这个也是我在实际工作中使用最多的Redux异步解决方案。 本文仍然是老套路,先来一个Redux-Saga的简单例子,然后我们自己写一个Redux-Saga来替代他,也就是源码分析。 Redux-Saga中这块代码是单独抽取了一个文件,我们仿照这种做法吧。 Redux-Saga增强了Redux的dispatch函数,在dispatch的同时会触发channel.put,也就是让Redux-Saga也响应回调。 本文可运行的代码已经上传到GitHub,可以拿下来玩玩:github.com/dennis-jian… 参考资料 Redux-Saga官方文档:redux-saga.js.org/ Redux-Saga
这个时候就需要redux-saga了。在redux-saga里saga就是一个可声明的组织良好的副作用实现方式(超时,API调用等等。。) saga不同,它们就像是运行在后台的守护任务(daemon task)一样有自己的运行逻辑(by Yasine Elouafi redux-saga的作者)。 所以,我们来看看如何在redux应用里添加saga。 一个saga本身就是一个副作用,就如同redux的reducer一样,绑定saga非常简单(但是很好的理解ES6的generator是非常有必要的)。 在之前的例子里,loadTodos saga在一开始就会触发。但是,如果我们想要每次一个action分发到store的时候触发saga要怎么做呢?
saga执行事件 收到补偿事件后执行补偿方法,并记录saga补偿执行事件 后面在解读时会逐一说明上述4大功能在代码上是如何实现的。 omega代码解读 参考添加saga的注解及相应的补偿方法,我们可以看到servicecomb-saga仅要求业务应用配置EnableOmega,@SagaStart,@Compensable这三个annotation incubator-servicecomb-saga/omega/omega-spring-starter/src/main/java/org/apache/servicecomb/saga/omega incubator-servicecomb-saga/omega/omega-spring-starter/src/main/java/org/apache/servicecomb/saga/omega 执行事件 通过对@Compensable这个annotation的AOP拦截处理,在本地事务开始与结束时记录saga执行事件,代码如下: incubator-servicecomb-saga/omega
原文地址:Consumer Sagas consumer saga是一个由CorrelationId标识的类,它定义了由saga repository持久化的状态。 除了状态之外,还可以向saga类添加接口,定义由saga处理的事件。这种状态和行为在单个类中的组合就是一个consumer saga。 在下面的示例中,定义了由SubmitOrder消息发起的order saga。 Orchestrates 要定义由现有的saga实例(如OrderAccepted)编排的事件,需要指定一个额外的接口和方法。 ,message) => saga.CorrelationId == message.OrderId; } Configuration 要在配置MassTransit时添加一个saga,请使用如下所示的
中不同的分布式事务解决方案: XA模式:强一致性分阶段事务模式,牺牲了一定的可用性,无业务侵入 TCC模式:最终一致的分阶段事务模式,有业务侵入 AT模式:最终一致的分阶段事务模式,无业务侵入,也是Seata的默认模式 SAGA 有代码侵入,需要人为编写try、Confirm和Cancel接口 软状态,事务是最终一致 需要考虑Confirm和Cancel的失败情况,做好幂等处理 # SAGA模式 Saga模式是SEATA提供的长事务解决方案 也分为两个阶段: 一阶段:直接提交本地事务(TCC是预留) 二阶段:成功则什么都不做;失败则通过编写补偿业务来回滚 Saga模式优点: 事务参与者可以基于事件驱动实现异步调用,吞吐高 一阶段直接提交事务 ,无锁,性能好 不用编写TCC中的三个阶段,实现简单 缺点: 软状态持续时间不确定,时效性差 没有锁,没有事务隔离,会有脏写 如图所示,SAGA模式下,事务一旦有一个出现问题,则反向按照事务调用顺序进行补偿 ,从而保证一致性 # 四种模式对比 - XA AT TCC SAGA 一致性 强一致 弱一致 弱一致 最终一致 隔离性 完全隔离 基于全局锁隔离 基于资源预留隔离 无隔离 代码侵入 无 无 有,需要编写
本文用以记录从调研Redux Saga,到应用到项目中的一些收获。 刚开始了解Saga时,看官方解释,并不是很清楚到底是什么?Saga的副作用(side effects)到底是什么? 使用Saga解决的问题 最初,在开始探究Saga之前,我们是希望寻求一种方式来隔离开应用前端的展现层,业务层和数据层。 -01.jpg 可以看到在使用了Saga后,react只负责数据如何展示,redux来负责数据的状态和绑定数据到react,而Saga处理了大部分复杂的业务逻辑。 选择Saga的原因 开始的时候一直在犹豫是否需要使用Saga或thunk,因为并不能很好的把握这两者到底解决了什么问题。
Saga saga是30年前的一篇数据库论文提到的概念。 论文中定义saga事务是一个长事务,整个事务可以由多个本地事务组成,每个本地事务有相应的执行模块和补偿模块,当saga事务中任意一个事务出错了,可以调用相关事务进行对应的补偿恢复,达到事务的最终一致性。 隔离性 saga事务没有准备阶段,不具备隔离性,如果多个saga事务同时操作同一资源会遇到多线程临界资源的情况,产生数据丢失或者脏数据。 Saga事务框架实现 组成部分: 服务发现模块 微服务处理模块 集中式/分布式saga协调器 saga执行模块 saga协调器 处理saga调用请求接收,分析及执行和结果查询等内容。 saga执行模块 通过分析请求的json数据,构建调用关系图谱,json用来描述saga事务串型调用子事务并执行子事务。
原文地址:Saga Overview Introduce 编排一系列事件的能力是一个强大的功能,而MassTransit使这成为可能。 saga是由协调器管理的长期事务。 saga是由事件发起的,saga编排事件,saga维护整个事务的状态。saga旨在管理分布式事务的复杂性,而不需要锁定和一致性。它们管理状态并跟踪发生部分故障时所需的任何补偿。 State Machine Sagas MassTransit包括Automatonymous,它提供了一个强大的状态机(State Machine)语法来创建saga。 Consumer Sagas MassTransit支持Comsumer Sagas,它实现一个或多个接口来消费相关的saga events。 包含此支持,以便将应用程序从其他saga实现轻松移动到MassTransit。 Definitions Saga 定义用于指定消费者的行为,以便可以自动配置它们。
前言React-Redux-Saga是一个用于处理Redux异步操作的中间件,它的实现原理基于生成器函数(Generator Functions)和事件监听模式。 本文的主题为 saga 的实现原理,那么与其说 sage 的实现原理,不如说在 saga 中如何通过 yield 获取异步返回的结果,在 React-Saga 中如何通过 yield 获取到数据之前,我还是建议去把博主在 好了,废话不多了,首先来看几个示例,对应的这几个案例分别说明了几个注意点,然后我们在实现 saga 中通过 yield 获取异步数据的底层实现代码,第一个示例如,定义了一个生成器函数, 这个函数保存了 然后调用定义的函数获取异步数据,然后在通过拿到的可迭代对象调用 next 方法将获取到的方法,传递给上一次 yield 进行变量赋值,然后我们在自定义生成器函数的 yield 当中就获取到异步数据了从而实现了 saga