哈喽,上一次跟大家分享了 spring 事务失效的一些场景,那正是因为这些失效的场景呢,我们在企业开发中直接用传单上的柱姐呢,用的会比较少,如果你想要控制好事物的一个力度的话,我们最好用编程式事物呢去实现。 那我们首先在项目中呢写了一个配置类 comfiviration, 然后呢我们给我们的项目中放入了一个并叫 platform 传 x manager, 这个就是我们的事物管理器,但我们事物管理器啊,它主要是要控制住我们的连接,所以呢,我们一定要把我们的 datasuce 给他注入进来, 所以需要给他设置进去。设置好我们的事物管理期之后啊,我们比如说我们来啊执行一下这样的一个逻辑,然后我们点进去看一下,然后这边我们就可以直接把我们的呃传家 x max 的给他拿过来,然后通过呃 get 传家 x 省开启我们的事务。 当然我们该的传家个省里面,我们需要传入一个叫传家个省减肥内省,相当于是我们事无助解的一些默认配置,那他呢是一个接口,他有很多的一个事先类, 那我们这边用的呢是一个叫 deforta tyxiantyphone nineteen, 是一个叫默认的事务定义,那我们就可以直接呢把我们的 thirty fourthaticson beautifulness 给它传过来,然后呢就相当于开启了我们的一个事物,然后我们需要用拆开时把我们事物提交的业务呢给它包裹上, 然后只要正常执行,我们就给他提交我们的数,然后只要异常执行呢,我们就给他回滚这样的一个数。 除此之外呢,我们 spring 还提供了一个工具类叫 true action template, 那用这个工具类呢,我们也可以直接去控制食物,那我们只需要用 true action template 的,然后去 xq 的,然后把我们的一个业务代码呢给他放进来,就可以对这样的一个业务代码呢进行事务的一个管控,而且呢 可以控制住这样的一个事物的力度,那我们可以看一下它底层是怎么实现的,比如说我们点进去好,点进去之后呢,这边我们可以看一下这样的一段代码,非常熟悉啊,我们用事物管理器呢去开启我们这样的一个事物, 然后开启事务之后呢,我们去执行我们的业务逻辑,执行业务逻辑之后啊,然后如果说啊有异常呢,我们就在这个方法里面去给他回滚掉,然后说如果正常执行的话,我们就直接用我们的事务管理器呢去提交我们的事务, 跟我们刚才写的那段逻辑呢,是几乎一模一样的啊,真正的业务逻辑呢,他就是这样的一个方法,然后呢我们只需要在这个方法里面啊去把我们的一个业务逻辑给他去实现一下就可以了。那如果说大家需要本期的 demo 以及往期的一些 demo 呢?大家可以到这里来 这个,然后给他发一个消息,像这样就可以拿到我们的一个呆萌,好,今天的分享呢就到这。
粉丝2.4万获赞27.3万

我们说到分布式事务呢,比较常见的就是这个插爱模式啊,基于数据库的事务,还有呢是 tcc 啊,基于补偿模式。那么还有一种呢啊,是这个 at 模式啊,用的也很多是阿里的这个 ct 推出的, 那么这两天呢,正好有一个分布式事务要写,我就用了一下这个,呃, it 模式还挺好用的,真的,就像这个 c 台文单上写的那样,没有做任何的代码侵入,只要引入一些啊简单的依赖,添加一个格罗波全赛克声哦,这个柱姐 对吧,那么所以他管理器呢,就帮你把这个事务给做了,确实呢,还挺方便的。那么说到这个 at 模式的原理啊,啊,也很好理解啊,同样也是两个阶段,一阶段呢就是提交数据啊,比如说你下单 哦,涉及到了 qq 存啊,又涉及到了出现订单,那这个时候呢,我们通过格罗波这四个神喽,这个柱姐呢啊,他就做了这个 aop 啊,前面拦截对吧,你的所有的搜口啊,每一个分支对数据库的操作都会记录在这个安都 logo 里面, 但是这个 log 呀,啊,不是数据股级别的,这个回滚日制,它是 c 塔自己解析的这个搜索语句啊,形成的日制,详细的记录了每一个步骤啊,这个是一阶段, 那么二阶段呢,就是判断每一个分支是不是都成功了啊,如果都成功了呢,那么之前写的 anglelog 回滚日制呢,就直接删除啊,全局所示范掉,那么其他的操作啊,可以进来,那么如果有一个分支失败啊,那么就直 行对应分支的安多罗尔的回款日制,原来扣减的库存,你得恢复到原来的数值,创建的订单呢也得取消掉,这个就是 at 模式的一个原理,核心呢就在于啊,代码没有侵入啊,只通过注解的方式就能够分析出数据库做了什么事情 啊,并且呢形成了一个啊叫做安都 logo 的日制啊,这些都是在 c 的层面来做的 啊,虽然很简单啊,也很方便啊,用的很爽,但是呢还是啊有一些问题的,比如说一个师傅在运作啊,在下单,在扣库存啊,在创建订单,这个时候呢,如果有另一个七线城过来, 这个时候呢是不让他读的啊,容易发生单独,怎么解决呢? ct 呢,就直接左侧了,所以呢确定还是很明显的性能不是那么的好 啊,在当前事务没结束的情况下面,全局所会把其他的县城主宰在门外,所以呢他其实是牺牲了一定的这个并发能力 啊,如果在一些这个性能要求比较高的场景,还是推荐大家用一些这个其他的补偿型的失误模式,比如说像这个 ttc, 像萨嘎,对吧, 虽然侵入代码,但是在并发性能上面要好很多。好了,本期的视频呢就这些了,如果您对本期的内容呢,有任何疑问,欢迎大家在评论区给我留言,谢谢大家!

请简要介绍一下什么是分布式事务,以及它的主要作用是什么?那么这道题的难度呢是比较低的,那么我这边所设定的一个岗位呢,是我们的终极工程师, 但是这道面试题,只要你碰到的企业里面,他里面所采用的架构是我们的微服务,或者说是分布式架构,那么基本上这是一道必问的题啊,所以说频率呢是比较高的。而面试官呢,他就是通过这道面试题去考察 你是不是具备了分布式的思维,因为只要你们系统流量比较大,那么或者是你们系统业务里面很多也比较杂,那么基本上那就是我们的分布式系统,或者说是我们微服价格没跑了。 如果说你连这道题你都答不好的话,那么基本上你和这个岗位的缘分呢也就到这里了啊。那么接下来呢,就带领大家去剖析一下。首先我们在回答这道面试题的时候, 我们先去和面试官去解释一下我们分布式事务的一个定义啊,分布式事务他指的是我们一个业务流程,比如说我们的下单,对吧?那么他是跨越了多个分布式系统或者说是服务的一个事务处理啊,比如说我们有订单,我们有库存,我们有支付, 那么我们要确保我们在这多个参与者之间,我们要保证他的数据一致性和他的一个原则性, 那么我们在面试过程当中呢,也不能输了,这么官方,对吧?那么他有点像一种巴古文的意思了,我们应该这么去答啊, 因为在我们以往的单机环境里面,我们基本上事物是靠数据库自身提供的特性来实现的,对吧?我们自己呢不用去操心的,但是一旦到了分布式环境,我们光靠数据库是兜不住的,因为我们机器节点他并不是我们的单机环境了,他已经有了 跨进程、跨节点、跨机器。那么最主要的一个原因呢,是有一个不靠谱的网络啊,我们的网络呢,他很有可能会导致我们网络分区啊,网络延迟啊,然后网络抖动啊等等等等啊, 他就有可能会导致一部分成功,一部分失败。那么我们整个业务流程呢,他就会出现问题,那么一堆脏数据,我们整个业务呢,也就跑不转了,对不对?我们通过这种方式呢,和面试官去解释一下分布事务的定义,然后我们再通过一个例子和面试官去举例论证啊, 我们看到我们下面呢是有一个电商的业务流程啊,假设我们在一个电商环境里面,那么我们的用户他可以在这个平台里面去下单,对吧?可以购买商品。那么这个电商平台呢,他的架构是一个微服务的架构,比如说他有订单服务、库存服务和我们的支付服务,那么当用户购买时 商品的时候,他需要执行以下的流程啊,比如说我要先在订单服里面去创建个新订单,然后再去叩见我们商品的库存,最后再去叩见我们用户的一个余额。那么这三个操作我们是不是要保持一个一致性? 如果在执行的过程当中,我们发生了一个异常,比如说我们在扣减库存的时候出现了网络故障,那么我这个订单是不是已经创建出来了,对吧?而我们的用户呢,也已经扣款了,那么这样呢,就会导致我们的数据不一致的问题啊, 所以说我们在使用分布式事务,那么他就是为了在跨多个服务,或者说是我们数据员的时候,我们要去保证我们数据的一致性,那么确保我们整个系统呢,他能够正常的运行啊。我们在这里和大家举的这个例子呢,只是作为一个参考,如果大家在真实的业务 场景里面有用过分布式事物的话,那么最好用自己实际的项目来举例子啊,那样是最好的,如果你没有机会接触,那么用我上面和大家说举的这个例子呢,也是可以的,如果大家有需要这份笔记的话,那么可以评论区扣一领取。

大家好,今天这个视频,我们一起来对 spring 事物回滚穿在身头做一下实际演示,希望能加深 你对这块的文字记忆。首先先在数据库中新建两张表, uz 和 udres 表,结构是这样的,用来直观的看到事物结果。 我们的项目中使用了 my beliefs plus 这样简单的单秒操作,就不用写对应的 circle 语句了。项目结构是这样的, ctrl 是入口,然后进入 user busy, 在这里面请调用这两个 service, 最后通过 mapper 操作数据库。我们这次介绍 四个例子,其他场景大家可以自行调试查。首先是复方法,加 transaction no 捕获异常, 然后手动回滚。十五,这种情况复方法就是在 b i z 里面的,这个方法必须能捕获到异常,也就是说此方法必须把异常抛出来,而不能在这里面出来开启掉。复方法 捕获到以后就会手动回关。十五,我们来看一下第一个例子,我们先来看一下如果正常情况下是不是成功保存, 可以看到正常情况下是能成功保存的,那我们来把它呢改成北京这个字,方法就会抛出异常,然后被这个复法 方法不过档, 我们可以看到这两个表里面都没有选择,可以看到打印出了 往右侧边里边插入数据的这个 set 语句,但是在保存地址的时候,这个方法会有报错,最终 保存用户的这这条数据就会被回关掉。其次是复方法,加 transaction 的里面加一个 robot for, 然后抛出一场,在这样抛出一场,而不是进行补货,如果补货的话,需要再抛出一个, 我们来执行一下同样的参数,可以看到是同样的没有新数据,然后第三个复方法加 transaction。 no 呃,这个异常不是有子 方法产生的了,而是在负方法里边产生,这个时候我们往这个 a 级里面传一个零,这样的话他会报一个异常, 可以看到没有新数据产生,可以看到在出现异常之前,这两个表里边的 sql 语句都执行副方法产生异常,然后子方法成功回国,最后使副方法不加这个事物的注解, 然后产生异常。这个时候我们是在此方法上加上这个 transaction 到主解,我们来看一下,结果 可以看到爆了一个没有失误的异常,那我们看一下有没有数据插入进去,可以看到此方法 插入了,也就是说副方法如果不加食物注解的话,它产生异常不会影响到此方法的食物规规。好了,希望通过上面四个例子 能帮助大家更明确事物回滚的使用方法,感谢观看下个视频见。

my circle 事务指的呢就是完成某个功能的整个过程,就称为一个事务,那么它有一个特点叫同生共死,就是说整个业务过程中出现了一点错误,那么咱们就说事务呢是失败的,那么整个过程都成功,那么这个时候呢,就说事务呢是成功的, 最典型的案例呢,就是我们的转账业务,比如说 a 要给 b 转三千,那么这个时候呢, a 的账户要减三千, b 的账户呢就要加三千,一定要保证 a 和 b 账户的金额呢,都改变了以后,才代表我们的这个整个的事物呢是成功的。 那么接下来的话呢,我们就这个案例给大家做一个相关的买 circle 的事物实现。首先呢要明确一点,就是买 circle 数据库呢,默认情况下呢是一个 circle, 据是一个事物, 也说每一个丝儿口语呢,在执行完以后呢,他就会自动的进行一个提交。那么接下来的话呢,我们可以先看一下什么呢?当前数据库的一个提交方式,那么下面这块呢,就是我们的这个查看的相关命令叫什么呢?搜,然后呢是 very ables like like, 然后呢是单引号北分号,中间的话呢叫什么呢? out two carmeter。 这样的话呢,大家会看到我们默认情况下呢,他的提交方式是应该是开启的,就是自动提交是开启的,那么这里边的话呢,我们是需要给他设置,为什么呢?手动提交, 设置的时候呢,我们设置是 set, 然后呢是 or two carmeit 等于什么呢?等于零给它设 设,为什么呢?设为手动提交,因为我们要保证是什么呢?两个 c 口语都执行完以后,然后呢我们才去提交事务,而不是每个 c 口语执行完以后呢自动提交,所以呢我们要给他设。为什么呢?手动提交, 作为手动提交以后呢,那么这个时候呢,咱们就需要什么呢?在更新什么呢?我们的账户的金额之前呢先去什么呢?开启我们的事务。开启事务的话呢,我们对应的命令的话呢叫什么呢? s t r t start, 然后呢是事务, 然后是穿的 c 穿 c 手,然后呢 c t i o n 回车 开启失误,开启完以后,然后呢接下来呢我们就可以什么呢?对用户的这个金额呢进行一个更新。那么目前的话呢,我们这里边呢是有两个账户,一个是额的命账户,一个是路特账户。假如说呢, 我现在的话呢是额的命账户,要给入头账户呢,去转什么呢?转十块钱。那么这个时候的话呢,你说额的命账户呢他要怎么呢?解十,然后呢入头账户的金额呢要加时,所以说咱们先来更新我们的这个额的命账户,更新语句的话呢应该是 update 啊,靠他。然后呢是设置什么的?设置他的这个金额金额的话呢列名,我们叫 money m o n e y money 等于什么?等于 m o n 意外 money。 解释,然后呢条件的话呢就是我们的这个对应的账户名,咱们的列名呢叫内幕。等于什么呢?等于奥特曼 回车,回车以后呢咱们再来什么呢?更新一下我们什么呢?我们 rot 账户的什么呢? 金额,那我们把我们把这个内幕呢改成入头,然后呢金额的话呢这块呢变成加十,接下来的话呢 回车,这样的话是相当于是我们这个整个的转账呢就结束了。如果说这块的话呢,两步都什么呢?都执行成功了,那我们这块的话呢就可以直接什么呢?去提交事务,提交事务的话呢,我们用的命令是什么呢?克密特 回车。然后接下来的话呢,我们再 select 星 from a c c o u n t 大家看一下对应的金额呢就全部个性成功了,这个呢就是一个完整的一个事物。当然如果说中间的话呢, 第一步更新成功了,然后第二个账户呢,在更新金额的时候如果是失败了,那么这个时候呢,我们就可以执行什么呢? robot, 然后呢完成一个事物的回滚。以上呢就是我们关于买 circle 的事物。

我们有一个买 clv 是这样一个类,它上面有一个 clv 的注解,表示他是十分荣幸一个兵对象, 这个内里边有两个方法,一个是方法 a, 一个是方法 b, 方法 a 上面带有事物的注解,表示它是一个事物方法,方法 b 上面没有事物注解,它是一个普通方法。我们在方法 b 里面呢调用带有事物注解的这个方法 a, 好,那现在问题是我们如果有一个抗缺了,现在要调用方法逼,那么此时我们的事物管理是怎样的? 好,那我们看一下。当我们考圈了调用方法 b 的时候,由于方法 b 他没有加事物注解,那么方法 b 是个普通方法,那就直接定调用,他就没有事物。但是我们方法 b 里 有个方法 a, 这个方法 a 是带有事物助解的,那么此时这个方法 a 是不是有事物呢?答案是没有事物。 我们考求了调用方法逼的时候,那方法逼他是一个来没有事物的方法,那么他相对是一个普通对象,不是一个代理对象。当我们有事物的时候,会产生一个代理对象,当我们没有事物的时候,是一个普通对象,那我们调一个普通对象的逼,方法 b 方法里面再钓 a, 方法相当于也是钓用一个来普通的 a, 方法不会,这个注解不会起作用。 如果我们是考求的单独电用这个方法 a, 那么这个时候是有事物的,我们通过电用方法 b, 方法 b 里边再电用方法 a, 那么这个时候方法 a 是没有事物的,因为他没有加上这个动态代理。

说人话中,实战讲干货。你好,欢迎来到 it 老齐的架构三百讲,我是你们的 it 私人顾问老齐。到今年呢,我从业已经十八年了,一直做扎瓦与架构的研发工作,今年呢,是我创业的第一年,目前呢,已经录制了十多门与编程架构相关的课程, 同时我还会提供点对点的简历优化、模拟面试、 offer 选择、解决方案、架构指导等服务。总之呢,只要是我有经验的,能给兄弟们帮上忙的信息呢,我一定坦诚相待。有需要的小伙伴呢,可以看一下评论区或者我的个人描述,希望能用我的经验帮你少走弯路,找到更好的工作。 今天咱们来聊一聊,在咱们整个分布式事物中,有一种叫 x a 的方案,那么作为 x a 方案呢,现在很多互联网的架构师呢,对他嗤之以鼻,其实啊,在我看来,很多时 都是在过度设计。那今天呢,我们就联合阿里 c 他呢,看一下 x c 方案是什么,以及阿里 c 他他是如何对 x c 的方案进行支持的。 首先呢,咱们来了解一下,到底什么是 x a 方案呢? x a 方案呢,也称 x 规范,是 x open 组织所定义的一种官方标准,它用于说明分布式事物的处理模式。 那作为 xc 方案呢,也是典型的两段式的处理,在我们著名的阿里巴巴的 cta 分布式事务解决方案中,在近期的版本呢,也对 xa 呢进行了支持,所以在日常开发中, 作为 x a 呢,也可以是我们在使用 set 中的一种选择。那到底 x a 方案是怎么回事呢?说白了呀,就是 x a 方案呢,作为业界 的一种分布式事物的标准,主流的关系型数据库,买 circle oricle 啊 p circle 等等等等,对他呢都有一些良好的支持。所以呢,在我们开发的时候,只要这个数据库是支持 x c 方案的,那作为阿里巴巴的 cta 这个分布式事物的中间线, 它就可以支持这个数据库,并提供相应的服务。那么作为 x a 到底是怎么回事呢?其实啊,非常的简单, 作为 x a 呢,它也是分成了两个阶段来进行处理的。首先左边的阶段叫做 prepare 阶段,也就是我们的准备阶段。作为准备阶段中呢,他会有三个角色, 一个叫 t m, 也就是事物管理器,说白了这个事物管理器呢,就是用来划分当前我们分布式事物的边 边界和范围在哪呢?这个是这么说,有点抽象,一会咱们看一眼代码你就明白了。而第二个 rm 就是资源管理器,他说白了他就是负责针对具体的数据库进行操作的。这样的一个角色, 那还有一个叫 t c, 也就是全局事务的协调者,用于事务注册以及全局事务的提交或者回滚的处理。 那么咱们结合场景来看一下假设呢,现在我有一个业务逻辑叫做 business service, 他呢是用来创建订单的,要知道创建订单往往需要由多个业务组合在成,也就是另外一个系统的订单服务下呢,来进行订单的新增。而除此以外呢,作为订单创建以后, 那对应用户的余额要进行减少,那这时又会涉及到 account 账户系统,那从我们设计的时候,原本的订单系统有一个团队来维护,一个账户系统有一个团队来维护, 同时作为我们这个商城的入口呢,他也有另外一个系统来维护,这是一个典型的分布式系统。那如何保障所有的 outer service 和 account service, 它要么全部提交,要么全部回滚呢?这里就可以考虑利用 x a 方案来实现了。 x a 方案下,只要我们数据库能够支持 x a, 那作为 set 这个中间键,它就可以进行支持。 那我下边来说一下它的处理过程。首先呢,作为第一个阶段 t m 下,它在启动的时候,创建订单前,会 自动的向 t c 也就是 set 的服务器发起一个注册全局事务,说明我要开始全局事务干活了。 紧接着商城呢,会去远程调用这个 order service, 也就是 r m 这端来完成 creat 订单创建的这样的操作。要知道,订单创建本质上就是在我们订单数据库中新增一个 insert 语句,完成订单信息的插入。 那么在 r m 这端,它要完成数据插入前,会自动的要和这个 t c c 它 server 呢?完成一个分支事物。 没错,在我们的分布式事务中,作为 t m 是控制全局事务,说明总的事情要开始干了,而分支事务则对应了这里,每一个步骤他都对应一个分支事务,他 也是会需要向 sata 来进行注册的。那作为 business service t m 呢?在调用完 creat 方法以后,完成了对于 order cool 的一个新增的操作。注意,这里 在进行新增操作时,只是去执行了 insert in two 语句,它并没有进行提交, 此时执行完死口是不提交的。而且作为另外一边,作为咱们这个账户库呢,他也是要 根据用户的编号去扣减余额,那他就会调用 account service 的 reduce 这个方法来扣减账户余额。 那么作为 account 库,它里边当然是用更新 update 语句来将指定账户的余额进行扣减。作为这两个 circle, 它都是只是完成执行,但是 是不会提交。在这个处理过程中,一旦 order service 点 create 方法对应成功, account service 点 reduce 方法,那当前就认为第一阶段处理完成了,那紧接着就会进入第二阶段。第二阶段的话,是由刚才的 business service 呢向 t c 呢,也就是 cd server 下达一个全局提交的命令,当下达全局提交以后,由这个 t c 呢主动地向两个 r m 这端来推送一个 commet 命令。 当卡密特命令收到以后,刚才我们这两条 circle 语句不是没提交吗?现在呢,都进行提交就完事了,那整体呢,就保证了我们数据的一致性。那在这个过程中有一个分支情况,假设我们 order service 处理成功了,但是 account service 因为余额不足处理失败,需要回滚的话,那么作为第二阶段呢,他下达的就是全局回滚的操作, 此时 t c 呢,会向 r m 下达 robec 命令,然后 r m 把刚才新增的 insert 语句给回滚掉就完事了。因为在这个过程中,所有的处理都是基于数据库的事物特性来完成的,所以呢,是可以保证整体 数据库的原子性,要么这些数据全部提交,要么这些数据全部回滚,这就是我们 xa 方案它的一个优势所在,可以保证我们数据的强一致,那这么说你应该了解了关于 xa 方案的执行流程,但是 xa 方案它在执行过程中 代码长什么样子,如何和 cat 结合来使用呢?我们来看一下代码就明白了,作为 cat 呢,它封装度是非常高的,在我们开发的时候,甚至你都可以把它理解成是一个本地系统来进行调用就可以了。 比如说咱们先来看 t m 端, t m 呢就是定义事物边界,也就是我们接入的入口这端, 在进入入口中,这里有个 purchase 购买的这样的一个方法。在 purchase 中有一个 sita 独有的注解叫 global transactional, 它的含义是开启全局事务。那么这里它的一个典型特性是,当开始执行 purchase 的时候,就自动的会在这个 business service 中向刚才的 t c 来下达一个注册全局事务的指令, 然后呢,程序进入运行,如果这个 protest 方法执行成功,则自动的进入二阶段去下达全局提交的命令。如果在中间过程任何一个执行步骤抛出了运行时的异常,他就会自动的向 tc 下达全局回滚的命令。 这个过程完全是由 seta global transactional 来给我们完成的,我们不需要额外的去控制。那么在这里每一个步骤呢?其实你可以看到稍微懂一点 spring club, 你可以发现这个通过 open fin 的方式呢,进行远程服务的调用,上面调用的是 account fin, 而下面都用的是 order fit。 我们先来看一下 order 这个服务,在 order 服务中啊,也就是每一个具体操作数据库的地方, 它呢需要做两件事,第一件事呢,就是在 r m 这端操作数据库之前呢,它需要 我们对现有的数据源 datasos 呢来进行一个包装,例如在演示代码中,这里它使用的是阿里巴巴著名的数据库连接词照一的来进行的处理。那么在下边你发现没有,在 构建 data sauce 的时候,它呢在原有的 joy the data sauce 中去 new data sauce proxy xa, 通过对原有数据员的包装呢,可以实现自动的这个分支事物的注册以及接收分支事物的提交或者回滚的操作,这一步非常的重要,因为他对我们原有的数据员进行了扩展。那么第 第二个呢,就是在我们业务方法中, order service, 那当然是用来进行新增操作的,所以你在实际开发的时候,就使用标准的声明式事物,通过 at transactional 描述这个业务方法,然后执行 insert in two 语句就完事了。 那在这个过程中,因为底层呢,都是基于数据源和各种各样的底层的 g, d, b, c 来实现的,所以你在数据操作时使用 hibernate 或者使用 my batis 都是没有任何影响的。哎,该怎么操作?怎么操作? 那当当前的这个 create 方法执行完了以后,那我们原有的 business, 那我们原有的方法呢,它就会向后执行,例如进入到了后面的这个 account service 扣减余额的这个部分,扣减余额部 粉在配置上也是一样的,还是要通过 data sost proxy xa 呢来进行对数据源的扩展和包装。然后呢,在这个 自己的业务代码中 account service 账户服务吗?那你就对从前台传入的用户编号和金额呢来进行一个相应的扣减就完事了。 那整体的逻辑我这么说你应该就明白了, t m 呢,就决定了事物的边界。确实,这里体现出的一个方法,方法执行成功,那自动的进行全局事物的提交。在二阶段的时候,由 seta server 主动地向各个 i m 来发起 comet。 如果这个方法中间有任何一个节点出现了问题,则会出现 robot 回滚的操作。我们之前处理的数据,比如说 insert, in to 或 或者是这个 update 语句,它都会被 robot 还原。因为作为 x a, 在一阶段我们执行了这个 circle 语句以后,它是不会立即提交的。注意,是不会立即提交的,它会在我们数据库的事物里边给 留存起来,等待 sata 下发的 comet 或者 robuck 指令,再完成后续的写盘或者回滚的操作。这便是 x c 方案它的一个处理逻辑所在。 那么针对于 x a 呢?它到底在日常工作中是怎么样的呢?它有什么好处和劣势呢?好处和劣势都非常明显,只要我们找到适合的场景, x a 仍然是一个优秀的选择。首先第一个,它是基于 c p 的设计,属于强一致的,尤其对数据 敏感性比较高的重要数据,采用 x a, 你会保证它不会出现丢数的情况。 第二个就是因为主流数关系型数据库呢,对 x a 呢,都是有支持的,属于业界标准了,它非常的稳定,而且支持广泛,不会像其他的民间自发的分布式事务方案一样,这个支持那个不支持,很恶心。 作为 xa 呢,大多数的主流的关系型数据库都是支持的,而第三种呢,就是二阶段提交呢,哎,他实现简单粗暴,也是人们最容易理解的一种分布式方案,对于代码的变化呢,也是非常少的,属于成熟稳定的。 那么 x a 的方案它的劣势呢,其实也是同样的明显的,第一个就是因为所有的操作都是基于数 数据库事务来进行的,我们新增的和修改的代码呢,都是在数据库的事务区里边来进行的操作, 所以在我们最终数据没有提交之前,这个事物里边的行呢,就会被夯住,也就是会被锁住。就像刚才我们对用户来进行余额更新的时候,那阶段一呢,那他就会在提交之前, 把这个 user id 等于对应编号的这行数据呢给夯住,那此时任何其他连接要对这条数据进行写操作的时候,都会被夯住,进入阻塞的状态,一旦阻塞,性能不就下来了吗?这是第一个情况, 而第二个情况是协议阻塞,因为在我们进行数据处理的时候, 在底层呢,其实建立的是一个长连接,那么这个长连接他在我们提交以后就会一直处于等待接收 set 反向推送 comet 或者 robot 命令, 那在这个过程中,如果我们的网络不稳定,或者呢这个呃收发的时间过长,在网络层面上他也会出现一个高延迟。同时作为常连接,在收到 x a 卡 meet 或者 x a robec 这种全局提交或者全局回滚命令之前,他都是处于阻塞等待的状态,这对于我们网络这个连接的利用率也是一个问题。 同时呢,还有一个更加严重的情况,我们举个例子,现在呢,我们来看一下假设呢,我们在 处理过程中,第一个数据库,它呢? auto service 正常处理成功,而第二个 account service 呢,甭管是因为什么原因,有可能是 c 口执行慢,也有可能是其他什么原因好,那他的网络不稳定,时断时续的,那作为 t c, 在建立好这个连接以后,他会尽量的去尝试完成这个工作。 假设完成这个 account service, 前前后后连同事啊带各种操作用了五秒钟时间,这就意味着前面已经处理完的 outer service 中,某一条数据呢,可能进入了长达五秒的被锁定的状态, 所以因为网络的原因,也可能会导致我们数据在操作时出现阻塞,这种情况下也是比较可怕的。所以说 啊,作为这个分布式事务下,强一致,他的代价就是低性能,这是我们无法避免的事情。 那同时呢,还有一个劣势,就是如果你使用了 x a 方案,就必须所有数据库都支持 x a, 否则你中间有一个不支持,那我们整体的全局事务就没法保证。 可是现在在互联网的这个大环境下,很多 o l t a p 数据库,也就是分析型的数据库呢,它本身就是不支持事物的,它就更提不上去支持 x a 了。那在这种 no circle 啊,大型渠道的互联网背景下,那你使用 x a 不就是跟自己找不自在吗? 所以说,这也是为什么在大多数企业互联网,尤其是靠前台的应用下,那使用 x a 几乎销声匿迹的主要原因,但是 xa 呢,仍然不失为一个很好的选择,尤其是在这个银行领域,因为大家都知道,银行领域在内部呢,实际上并不是一个高并发系统。你可能会觉得,哇,银行一天这么多人在用,他的并发量会很高吧?其实不是的, 银行他的数据量很大,他的并发量其实往往并不是特别高。同时呢,作为除了核心业务系统以外,他的这种数据冲突也是相对较少的。什么意思呢?你比如说我们像刚才什么情况下会出现严重的这种啊 行等待所等待的状态呢?就是我们如果说同时有一百个人给我这个账户来转账的话,那么如果采用 x c 方案,强一致,前边人转不完,后边人我们就 一直处于阻塞的状态,这也是基于 c p 强一致的一个问题所在。但是你是想过没有,除非非常特殊的业务,像什么结算账户,好一天几百上千笔向同一个账户进行结算, 除了这种极端情况下,大部分的账户,像你的我的账户一天能有多少笔收款和入款呢?针对于这个数据,我们写冲突的可能性又有多大呢? 所以这种可能性针对于我们,比如说像银行个金出啊这样的业务场景呢,就是非常适合的,因为他的数据冲突相对比较小,同时呢, 在银行体量中,他的这个并发量按照现在互联网对比来说也属于低并发。因此像这样的应用场景呢,是适合 x a 的。而且大家也要明白,咱们现 在天天都在喊高可用高并发,可是真正的你想过没有?真正高并发的系统有多少啊? 那所以在我们自己来进行业务开发的时候,你为了去保证数据,所谓的这种呃高效的执行采用了 a p 方案,或者采用了一堆补偿方案,但是你想想真的有这个必要吗?如果我们是在低并发或者数据冲突较少的情况下, x a 真的是一种非常好的选择,尤其是在企业级游泳时,这是一个很好的处理方案。好的,那我费了半天口舌。那如果你能真的听到这里,那说明真的是真爱粉了,那给个三连不过分吧。谢谢兄弟。