范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

分布式事务,原理简单,写起来全是坑

  今天我们就一起来看下另一种模式,XA 模式!
  其实我觉得 seata 中的四种不同的分布式事务模式,学完 AT、TCC 以及 XA 就够了,Saga 不好玩,而且长事务本身就有很多问题,也不推荐使用。
  Seata 中的 XA 模式实际上是基于 MySQL 的 XA 两阶段提交发展出来的,所以学习 XA 模式,需要小伙伴们先理解 MySQL 中的 XA 是怎么一回事,把 MySQL 中的 XA 搞清楚了,再来学习 Seata 中的 XA 模式就容易的多了。  1. 什么是 XA 规范1.1 什么是两阶段提交
  我们先来稍微回顾一下两阶段提交。
  先来看下面一张图:
  这张图里涉及到三个概念:  AP:这个不用多说,AP 就是应用程序本身。  RM:RM 是资源管理器,也就是事务的参与者,大部分情况下就是指数据库,一个分布式事务往往涉及到多个 RM。  TM:TM 就是事务管理器,创建分布式事务并协调分布式事务中的各个子事务的执行和状态,子事务就是指在 RM 上执行的具体操作。
  那么什么是两阶段(Two-Phase Commit, 简称 2PC)提交?
  两阶段提交说白了道理很简单,松哥举个简单例子来和大家说明两阶段提交:
  比如下面一张图:
  我们在 Business 中分别调用 Storage 与 Order、Account,这三个中的操作要同时成功或者同时失败,但是由于这三个分处于不同服务,因此我们只能先让这三个服务中的操作各自执行,三个服务中的事务各自执行就是两阶段中的第一阶段。
  第一阶段执行完毕后,先不要急着提交,因为三个服务中有的可能执行失败了,此时需要三个服务各自把自己一阶段的执行结果报告给一个事务协调者(也就是前面文章中的 Seata Server),事务协调者收到消息后,如果三个服务的一阶段都执行成功了,此时就通知三个事务分别提交,如果三个服务中有服务执行失败了,此时就通知三个事务分别回滚。
  这就是所谓的两阶段提交。
  总结一下:两阶段提交中,事务分为参与者(例如上图的各个具体服务)与协调者(上文案例中的 Seata Server),参与者将操作成败通知协调者,再由协调者根据所有参与者的反馈情报决定各参与者是要提交操作还是中止操作,这里的参与者可以理解为 RM,协调者可以理解为 TM。
  不过 Seata 中的各个分布式事务模式,基本都是在二阶段提交的基础上演化出来的,因此并不完全一样,这点需要小伙伴们注意。  1.2 什么是 XA 规范
  XA 规范 是 X/Open 组织定义的分布式事务处理(DTP,Distributed Transaction Processing)标准。
  XA 规范描述了全局的事务管理器与局部的资源管理器之间的接口。XA规范的目的是允许多个资源(如数据库,应用服务器,消息队列等)在同一事务中访问,这样可以使  ACID  属性跨越应用程序而保持有效。
  XA 规范使用两阶段提交来保证所有资源同时提交或回滚任何特定的事务。
  XA 规范在上世纪 90 年代初就被提出。目前,几乎所有主流的数据库都对 XA 规范提供了支持。
  XA 事务的基础是两阶段提交协议。需要有一个事务协调者来保证所有的事务参与者都完成了准备工作(第一阶段)。如果协调者收到所有参与者都准备好的消息,就会通知所有的事务都可以提交了(第二阶段)。MySQL 在这个 XA 事务中扮演的是参与者的角色,而不是协调者(事务管理器)。
  MySQL 的 XA 事务分为内部 XA 和外部 XA。外部 XA 可以参与到外部的分布式事务中,需要应用层介入作为协调者;内部 XA 事务用于同一实例下跨多引擎事务,由 Binlog 作为协调者,比如在一个存储引擎提交时,需要将提交信息写入二进制日志,这就是一个分布式内部 XA 事务,只不过二进制日志的参与者是 MySQL 本身。MySQL 在 XA 事务中扮演的是一个参与者的角色,而不是协调者。  2. MySQL 中的 XA
  接下来松哥通过一个简单的例子先给大家看下 MySQL 中的 XA 是怎么玩的。  2.1 两阶段事务提交
  比如说转账操作,我用 MySQL 中的 XA 事务来和大家演示一下从一个账户中转出 10 块钱:
  上面这段事务提交是一个两阶段事务提交的案例。
  具体执行步骤如下:  XA START "transfer_money" :这个表示开启一个 XA 事务,后面的字符串是事务的 xid,这是一个唯一字符串,开启之后,事务的状态变为 ACTIVE 。 update account set amount=amount-10 where account_no="A" ; 这个表示执行具体的 SQL。 XA END "transfer_money" :这个表示结束一个 XA 事务,此时事务的状态转为 IDLE 。 XA PREPARE "transfer_money" :这个将事务置为 PREPARE 状态。 XA COMMIT "transfer_money" :这个用来提交事务,提交之后,事务的状态就是 COMMITED。
  最后一步,可以通过  XA COMMIT  来提交,也可以通过 XA ROLLBACK  来回滚,回滚后事务的状态就是 ROLLBACK。
  另外第四步可以省略,即一个 IDLE 状态的 XA 事务可以直接提交或者回滚。
  我们来看下面一张流程图:
  从这张图里我们可以看出,事务可以一步提交,也可以两阶段提交,都是支持的。如果是两阶段提交,prepare 之后,其实是在等其他的资源管理器(RM)反馈结果。  2.2 事务直接提交
  松哥再给大家演示一下事务一步提交:
  这个就比较简单,没啥好说的。
  这块再跟大家介绍另外一个 XA 事务相关的命令  XA RECOVER ,如下图:
  XA RECOVER  可以列出所有处于 PREPARE 状态的 XA 事务,其他状态的事务则都不会列出来,如上图。 2.3 事务回滚
  再举一个事务回滚的例子:
  小伙伴们看到, xa recover  可以查看处于 prepare 状态的事务,事务回滚有三个参数:第一个参数,是以 gtrid_length 为依据,从 data 字符串上截取下来的值;第二个参数,是第一个从 data 上截取下来值之后,data 剩余的值,在本案例中,第一次被截取之后,就不剩了,所以第二个参数是一个空字符串;第三个参数是 formatID 的值。
  回滚之后,再执行  xa recover  就看不到东西了。 2.4 小结
  在用一个客户端环境下,XA 事务和本地(非 XA )事务互相排斥,如果已经通过 XA START 来开启一个事务,则本地事务不会被启动,直到 XA 事务被提交或者被回滚为止。
  相反的,如果已经使用 START TRANSACTION 启动一个本地事务,则 XA 语句不能被使用,直到该事务被提交或者回滚为止,而且 XA 事务仅仅被 InnoDB 存储引擎支持。  3. Seata 中的 XA3.1 Seata 中的 XA 模式
  我们先来看一点理论知识,3.3 小节我们再来看代码实践。
  通过上面的介绍,大家已经知道了 MySQL 中的 XA 事务是怎么回事了,Seata 中的 XA 模式其实就是在 MySQL 中 XA 模式的基础上实现的。Seata 中的 XA 模式就是在 Seata 定义的分布式事务框架内,利用事务资源(数据库、消息服务等)对 XA 协议的支持,以 XA 协议的机制来管理分支事务的一种事务模式。
  我们来看下面一张图:
  我来大概说一下这个执行步骤:  首先由 TM 开启全局分布式事务。  各个业务 SQL 分别放在不同的 XA 分支中进行,具体执行的流程就是  XA Start ->业务 SQL ->XA End ,这个流程跟我 2.1 小节和大家演示的 MySQL 中 XA 事务的流程是一致的。 分支中的 XA 事务执行完成后,执行  XA prepare ,并将自己执行的状态报告给 TC。 其他的分支事务均按照 2、3 步骤来执行。  当所有分支事务都执行完毕后,TC 也收到了各个分支事务报告上来的执行状态,如果所有状态都 OK,则 TC 通知所有 RM 执行  XA Commit  完成事务的最终提交,否则 TC 通知所有 RM 执行 XA Rollback  进行事务回滚。
  这就是 Seata 中的 XA 模式!只要小伙伴们理解了 2.2 小节中 MySQL 的 XA 模式,那么 Seata 中的 XA 模式就很好理解了。  3.2 特色
  前面小伙伴们已经学会了 AT 和 TCC 两种不同的分布式事务模式了,现在再加入一个 XA,我们再来把这三个放在一起比较下。  AT 和 TCC 都是通过反向补偿将数据复原的,也就是说,通过一条更新语句将数据复原;XA 因为是 MySQL 自己的功能,所以不是反向补偿,而是正儿八经的回滚(处于 prepare 状态的数据并没有 commit,将来在二阶段可以选择 commit 或者 rollback)。  AT 和 XA 模式是无侵入的分布式事务解决方案,适用于不希望对业务进行改造的场景,几乎0学习成本;TCC 则有一定的代码侵入。  AT 和 XA 都是一种全自动的,无论是提交呀,回滚呀(无论是真回滚还是反向补偿),都是全自动的,就是开发者基本上不需要额外做什么事情;TCC 则是一种手动的分布式事务,一阶段的 prepare、二阶段的 commit 或者 rollback,所有逻辑都是开发者自己写的。  松哥发前面文章的时候,有小伙伴提到分布式事务的一致性问题,XA 模式是分布式强一致性的解决方案,但是因为性能低而导致使用较少。
  好啦,比较完啦,那就上代码吧!  3.3 代码实践
  小伙伴们只需要搞明白前面的 AT 模式后,XA 模式其实跟 AT 模式差不多!就是替换一下数据源即可!话是这么说,不过真做起来,还是有很多坑,我们一起来看下。
  为了方便大家理解,本文我就不重新搞案例了,咱们还用上篇文章那个下订单的案例来演示。
  这是一个商品下单的案例,一共有五个服务,我来和大家稍微解释下:  eureka:这是服务注册中心。  account:这是账户服务,可以查询/修改用户的账户信息(主要是账户余额)。  order:这是订单服务,可以下订单。  storage:这是一个仓储服务,可以查询/修改商品的库存数量。  bussiness:这是业务,用户下单操作将在这里完成。
  这个案例讲了一个什么事呢?
  当用户想要下单的时候,调用了 bussiness 中的接口,bussiness 中的接口又调用了它自己的 service,在 service 中,首先开启了全局分布式事务,然后通过 feign 调用 storage 中的接口去扣库存,然后再通过 feign 调用 order 中的接口去创建订单(order 在创建订单的时候,不仅会创建订单,还会扣除用户账户的余额),在这个过程中,如果有任何一个环节出错了(余额不足、库存不足等导致的问题),就会触发整体的事务回滚。
  本案例具体架构如下图:
  这个案例就是一个典型的分布式事务问题,storage、order 以及 account 中的事务分属于不同的微服务,但是我们希望他们同时成功或者同时失败。
  这个案例的基本架构我这里就不重复搭建了,小伙伴们可以参考上篇文章,这里我们主要来看 XA 事务如何添加进来。  3.3.1 数据库配置
  由于 XA 模式利用的是 MySQL 自身对 XA 规范的实现,所以 XA 机制实际上是不需要 undo_log 表的, 小伙伴们可以把你 AT 模式中的 undo_log 表删除啦   如果删除后运行 Java 程序报错,那说明你的 XA 模式使用的不地道!注意看松哥后面的讲解哦。
  接下来我就来说几个要点。  数据库驱动
  这是一个坑。松哥经过反复测试,seata 中的 XA 模式和最新版的 MySQL 驱动不兼容,运行时候会有错误,经过测试,MySQL 8.0.11 这个版本的驱动是没问题的,所以在 account、storage 以及 order 三个需要数据库调用的服务上,记得修改一下数据库驱动依赖的版本号:       mysql     mysql-connector-java     runtime     8.0.11  druid 依赖
  有的小伙伴们看到这里用到了阿里的 Druid 数据库连接池,就赶紧加入这个依赖!殊不知,这又掉入版本兼容的坑了, spring-cloud-starter-alibaba-seata  依赖中实际上包含了 druid 依赖,而且版本号是没有问题的!所以小伙伴们千万别自己手动加 druid 依赖,可能会因为版本号问题掉坑。 关掉数据源代码
  接下来就是关闭掉 seata 数据源代理了,account、storage 以及 order 里边都改一下,加入如下配置:  seata.enable-auto-data-source-proxy=false配置自定义数据源
  接下来就是配置自定义数据源了,account、order 以及 storage 都要配置,如下:  @Configuration public class DataSourceConfiguration {      @Bean     @ConfigurationProperties(prefix = "spring.datasource")     public DruidDataSource druidDataSource() {         return new DruidDataSource();     }      @Bean("dataSourceProxy")     @Primary     public DataSource dataSource(DruidDataSource druidDataSource) {         return new DataSourceProxyXA(druidDataSource);     }       @Bean     public SqlSessionFactory sqlSessionFactory(DataSource dataSourceProxy)throws Exception{         SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();         sqlSessionFactoryBean.setDataSource(dataSourceProxy);         sqlSessionFactoryBean.setTransactionFactory(new SpringManagedTransactionFactory());         return sqlSessionFactoryBean.getObject();     }  }
  先配置 DruidDataSource,但这不是我们最终目的,最终目的是配置 DataSourceProxyXA,看名字就知道,这就会把事务切换为 XA 模式,最后,还需要基于 DataSourceProxyXA 来配置一下 MyBatis,都是常规操作,不多说。
  好啦,就这样,我们的 seata XA 模式就配置好啦 其他的代码都和 AT 模式一样,不再赘述。
  原文链接:https://mp.weixin.qq.com/s/29PmqK_bzDgh8bl9SBY3Uw

一个体制浪浪山老干部言谈举止引发的思考我的生活也是头条体制到底埋没了多少人才?尊重是基于年龄还是德行品格操守?谦虚理性平和沟通为啥越来越难?承认人本身认知的局限能力的有限为啥这么难?体制是啥?是年轻人的围城!是千军万马收获收获作者浥尘主播撒欢儿的骆驼新闻联播说全国秋粮已收获了四成七天长假我收获了七首诗每天早晨她们就长成了在我的窗台床前桌上我把情绪的镰刀擦得又快又亮一行行割下来颗粒归仓什么时候种下的可意志力真的能帮助我们么?我们轻松就能看出,别人只要做出一点点改变,就能够变得更好。但是当别人建议我们改变的时候,我们却会找出各种各样的理由逃避改变。我们甚至会反驳那些给我们建议的人,认为他们的建议太自以为新年第一锅!嵩县家门口就能泡的网红汤泉!玉兔添新意花样过春节冬季玩雪白云山,春节假期不打烊!新年快乐过家乡年味,来洛阳白云山除了景区内的景点和游玩设施以外有独一无二的网红铁锅汤泉温暖养生的冬季美食年味十足的花灯展免费畅玩二次感染增多,提醒大家多吃4种高维C菜,营养充足少遭罪!二次感染增多,提醒大姐多吃4种高维C菜,营养充足少遭罪!最近听到一部分人开始复阳了,二次感染的人也开始增多。所以即便是阳过一次,每天我们还是得像以前那样做好防护,别掉以轻心了。我们大寒将至,老话说大寒吃5宝,丢掉老棉袄,指的是哪5宝?时光荏苒,转眼来到今年的最后一个节气大寒。本应是极度寒冷的一段时间,却因为临近年末,让人们忘却了寒冷萧瑟之意,投入到对新年的期盼中。所以大寒虽然温度低,但人们心里是暖的,这是辞旧迎过年了特别要管好我们的嘴1多喝水,少吃甜食。这是因为糖类容易让人发胖,多喝水可以预防肥胖。2多吃蔬菜和水果。蔬菜和水果中含有大量的维生素,这些维生素对于我们人体是非常重要的,它们可以促进我们的新陈代谢,帮水果加热吃,会破坏营养吗?冬季气温低,胃肠功能较弱牙口不好的老年人,往往不敢吃冰凉的水果。有的老年人会把水果加热吃,认为熟吃水果有利养生也有人担心加热会导致水果中的营养成分流失。那么,水果加热吃会破坏营养吗为什么你们的新发型新包包都这么好看!晚上好。前几天去重庆出差,连吃了3天火锅还没吃够,果然还得是重庆的火锅,最好吃!再过4天就要放春节假期了,好期待,这几天心已经飞走了赶在放假前再来一期贝壳分享,看看小伙伴们的日常小从头到脚!日清跨界联名从食品改到鞋子,海鮮味潮鞋出炉善于搞怪的日清跨界合作五花八门,此次又从头移到脚,近日他们写手潮牌公司Converse,共同推出搞怪味十足的ALLSTARCUPNOODLEHI潮鞋。潮鞋以CUPNOODLE为造型烫头发种睫毛做美甲!人均花费千元的过年三件套火了俗话说有钱没钱,剃头过年。春节临近,昆明街头大大小小的理发店美甲店已开启过年模式,很多女生都赶在大年三十之前修剪烫染头发,换个全新造型,然后再种个睫毛做个美甲,美美地过年。1月14
百法信为先,修行善为念初开始修行,道心初萌发,内心还不太坚定自己选择走这条路到底对不对,在遇到一些阻碍时,内心产生动摇,就会产生疑念,内魔就可能就会放大这个漏洞,此时内心经过一些挣扎,清醒了,就会更加坚随遇而安,转念升华,庄重圆融一是随遇而安。马克思主义哲学的实践观点告诉我们,人在事上练,刀在石上磨。人生在世,唯有经事多,见事深,悟事透,看事远,阅事明,方能遇事不慌不忙,平静平和,接纳臣服,厚德载福。同时,陈寅恪说的几千年来亿万人其实都在为一个是人不是人陈寅恪说的几千年来亿万人其实都在为一个是人不是人2023418陈寅恪中国人的进步,其实目标很低你是人,我也是。然而,就是这最低的努力,都要耗费几千年,还一直在努力中。经常,时不时弄因为弟媳,鲁迅每月工资被扣,和周作人针锋相对,还被赶出自己家如哥斯达黎加米列所说越是善良的人,越察觉不出别人的居心不良。我们生来都尽量让自己做个善良的人,以好心待人,尽力去帮助他人,这是人性的本善,而善良的人之所以愿意善良,是因为相信好心有让一个普通学生闪闪发光,教师要做对哪些事?曾经的我,现在的小涵2000年夏,慵懒的阳光透过窗户,语文张老师正在讲台上点评范文。我仿佛站在舞台中央,有一束追光照着自己,照得我耳根绯红。因为那是我的作文第一次被当作范文朗读。我如果人到中年,要随礼就要记住4不随,不必为了面子而吃亏!如今的社会中,人与人之间的交往变得十分复杂。不管是个人的日常生活还是家庭社交和其他社会活动,为了更好地融入社会生活,我们有时不得不做一些自己并不情愿的事情。在这些过程中,我们就必须活在每一个我应该活在的当下(疗愈书籍节选)活在每一个我应该活在的当下小七想必很多孩子跟我一样,曾将时间碎片化,这段时间应该做什么工作,那段时间是可以休息的这里的休息指的是无意识的休息,完全被小我意识带着跑,无意识的沉浸在小每日好诗那么多树叶竖起耳朵关注,让诗歌点亮生活那么多树叶竖起耳朵车延高那么多树叶竖起耳朵只几声啼叫,让人听懂了杜鹃泣血天已擦黑振动的翅翼,还是鼓起凉风像一片陌生的叶子,向远处飘零天上有另一种路却是一样的风雨散文诵读(真人语音)西安市长安杨庄街办西安最美拍照打卡地又见杨庄四月天作者鲁晓龙诵读者王明利音频作品为长安融媒颂您一个长安栏目原创转录请注明出处!丽日当空,春光烂漫,这个季节里杨庄春天应该别有一番景致吧!人间四月芳菲尽,杨庄春花次第开!海外生活hello我是Kelly。很多人问普通人也可以来美国打工吗?众所周知美国是经济高度发达的国家,有很多人都想要来美国工作发展。办理美国签证就可以在美国工作了。想要合法在美国工作可以申油菜花开春意浓乡村美景入画来4月15日,市民在油菜花海中拍照。通讯员李茜摄连日来,大城县各地的油菜花露出金灿灿的笑脸。众多游客移步乡间油菜田,那抹盛开的暖黄随即热传朋友圈。在杜权村东,数百亩油菜花竞相绽放,片