有关网站建设的外文参考文献,wordpress简约主题分享,做网站的人找不到了,单县住房和城乡建设局网站目录
背景介绍什么是分布式事务什么叫做逆向补偿呢互联网最流行的分布式事务组件seata总结
背景
大家好#xff0c;今天给大家分享一个在2022年出去面试Java几乎必问的一个技术#xff0c;那就是seata。什么#xff1f;#xff1f;你才看了第一句话心里有闪现了无数个问… 目录
背景介绍什么是分布式事务什么叫做逆向补偿呢互联网最流行的分布式事务组件seata总结
背景
大家好今天给大家分享一个在2022年出去面试Java几乎必问的一个技术那就是seata。什么你才看了第一句话心里有闪现了无数个问号因为没听说过seata这个东西没关系为了避免兄弟们出去面试被问到seata的时候一脸蒙圈我们今天就把这个东西给大家讲明白。
既然要给大家讲什么是seata那就得先说一下这个东西的定位这东西就是现在很火的 spring cloud alibaba里的一个组件是专门帮助我们解决分布式事务问题的也就是说seata是一个分布式事务框架。
什么是分布式事务
那可能很多小伙伴很蒙圈了什么是分布式事务 好吧为了保证大家能继续看下去我们先说一下什么是分布式事务这个问题。
举个最简单的例子假设现在你负责了一个订单系统一个库存系统一个营销系统然后呢当你的订单系统收到用户一个请求要创建订单的时候这个时候你得做三件事情第一调用库存系统的接口锁定库存第二调用营销系统的接口锁定优惠券第三你订单系统自己得在MySQL里插入一系列订单的数据比如下图1所示 图1
那么现在问题来了你订单系统有自己的订单数据库可以去插入订单数据那库存系统是不是也应该有自己的库存数据库去锁定库存数据营销系统是不是应该有自己的营销数据库去锁定优惠券当然是了每个人都有自己的数据库这一个都不能少如下图2所示 图2
那现在问题又来了既然一次创建订单的请求要涉及到订单、库存、营销三个系统分别操作各自自己的三个数据库才能完成这次请求。
那是不是可能会出现这么一种情况首先呢你先调用库存系统锁定了库存了O了。接着呢你又调用了营销系统锁定了优惠券也O了。最后呢当你订单系统要往自己的订单数据库里插入数据的时候网络抽风了导致你这一次插入订单数据失败了直接exception异常了你蒙圈了如下图3所示 图3
那这个时候你觉得可能会产生什么样的问题呢其实很简单这个时候你这个订单要购买的商品库存已经被锁定了你为了下这个订单用的优惠券也已经被锁定了结果呢你的订单自己本身的数据并没进入数据库然后还返回一个了异常信息给用户说本次下单失败。 但是你说下单失败就失败吧结果呢运营看库存数据的时候可能会一脸蒙圈为啥有一些商品库存被锁定了结果没有对应的跟订单而且一直没人付款来购买呢然后用户自己也有点发蒙因为一查自己的优惠券好不容易攒了几张券来买东西结果现在订单没下成优惠券状态都搞成已使用了自己还没法用这些优惠券了如下图4所示 图4
其实这就是一个非常经典的分布式事务的问题了你一个创建订单的请求横跨了订单、库存、营销三个系统分别涉及三个数据库所有很可能会发现你的库存和营销的数据操作都成功了而且库存和营销数据库里的本地事务都提交了结果订单插入数据库失败了订单数据库里的本地事务回滚了但是库存和营销数据库里的本地事务已经提交了他们是不会回滚的如下图5所示 图5
什么叫做逆向补偿呢
那既然问题已经找到了我们希望的应该是什么效果呢我们其实希望的效果是如果订单要是插入数据库失败了订单数据库本地事务回滚了我们应该想办法去通知一下库存系统和营销系统把之前在库存数据库和营销数据库里已经提交的数据修改做一个逆向补偿进行恢复。
什么叫做逆向补偿呢 意思就是说之前库存系统如果在数据库里执行的是insert那么此时就应该执行delete把之前插入的数据删除了如果之前执行的delete现在就应该执行insert把删除的额数据重新插入回去如果之前执行的是udpate语句现在就应该再次执行一个update语句把数据恢复到更新之前的状态如下图6所示 图6
互联网最流行的分布式事务组件seata
那既然我们想要实现这个效果这个时候问题就来了单单依赖我们自己那肯定搞不定这个问题了这个时候就必须引入spring cloud alibaba里的大佬组件seata。seata就是专门帮助我们解决这个问题的如果我们要是在系统里引入seata框架之后其实每个系统里都会嵌入seata同时我们还需要去部署一个seata server如下图7所示 图7
这个时候我们的系统运行原理会变成这样订单系统中的seata会发送请求给seata server去开启一个全局事务然后库存系统先运行他在进行数据库crud的时候这些操作都会被seata框架进行拦截然后seata框架会在一个本地事务里把你的sql语句和逆向补偿日志一起插入到你的库存数据库里去在库存数据库里必须有一个undo_log表存储seata的逆向补偿日志。
那这个逆向补偿日志是什么呢简单如果你的sql是insert那逆向补偿日志可以帮助你后续构建delete语句来删除如果你的sql是update那逆向补偿日志可以记录你更新之前的旧数据他可以帮助你后续把数据update到老版本的状态如下图8所示 图8
你库存系统的sql语句和他们的补偿日志是在一个本地事务里一起提交的一起成功或者一起失败所以但凡你的库存系统更新成功了就一定会有对应的补偿日志也会在库存数据库里的以备不时之需营销系统其实也是相同的运行原理。
那么假设说库存系统和营销系统按照这个思路都执行完毕了到订单系统了他结果撂挑子了插入订单数据库失败当然在插入的时候其实也会有对应的补偿日志会一起提交但是因为这个时候网络问题导致插入订单和插入补偿日志一起失败了所以此时订单系统的seata就会上报seata server说大哥我这儿完犊子了您要不通知库存和营销两个兄弟逆向补偿一下吧如下图9所示 图9
接着seata server发现说这分布式事务都失败了那赶紧的他会通知库存系统和营销系统里的seata框架小兄弟说兄弟们赶紧的把之前插入你们数据库里的undo_log表里的补偿日志拿出来构建一下逆向补偿sql之前是insert你就给我弄个delete之前是delete你就给我弄个insert之前是update你还是update逆向补偿sql赶紧跑一把把数据给我恢复了前队改后队跑步前进hurry up起来如下图10所示 图10
总结