00:03
好,下面我们来看事物消息。呃,关于这个事物,消息比前面的都要复杂。呃,我们关于事物消息呢,从这样一个场景说起。那么工行用户A要向建行用户B转账1万块钱啊,这一个转账的问题对吧?哎,说了我们可以使用同步消息来处理这个需求。这是个图,我们看这个图就行了啊,下边一个简单的一个步骤,第一步呢,我们工行系统啊先。向我们的brokeer是吧,发送一个消息M,那这个消息什么呢?就是呃,我要给。币是吧,给建行啊,这个用户币啊,增加1万块钱啊,我把这个消息发给他了。放以后呢?呃,这是个同步消息是吧,然后我这个博ER啊,发送成功给了我们的工行系统。
01:02
那么公安系统接收完这个成功APP以后呢,诶,我就从我工行里边扣扣钱的,我要扣1万块钱呢,是吧,我这扣钱扣1万。然后呢,来第四步对吧,然后这个这个这个。建行系统啊,啊,我们实际上他工行系统是作为我们消息的生产者,然后建行系统是我们消息的消费者,建行系统把消息的掳走。得到以后我要干嘛消费这个消息怎么消费?所谓的消费就是。读了这个消息以后啊,完成从用户币啊,啊不是应该是向用户币啊,增加1万块钱。对吧,向用户币增加1万块钱,诶这就整个这个过程完成了啊,他就转让工作已经完成了。这个啊,看似没有问题。啊,其实这里边儿问题还是很大的。
02:00
什么问题呢?大家想一下,如果说。我这扣款失败了。第三步的时候。扣款10万,余额不不足。是吧,扣款失败了,但是大家想一下,我这消息是不是已经发到博了?你消息一旦发到。也就是说我这个消费者就可以把它消费了。然后这样就给他里边增加了1万块钱,这倒挺好,你这样扣款没成功,这边增加了,那行不行,肯定是不行的呀。是不是所以啊,我们说啊,嗯,这里边儿啊,呃,这。其中。呃,是有。问题的。呃,什么问题呢?若呃,第三。雾中。的扣款操作。失败,那不管因为什么原因,反正失败了啊,失败。
03:02
呃。在。消息已经成功。发送。到了。不好看。是吧?那对于。对于MQ来说啊,呃,只要消息写入。成功。那么这个消息就可以对吧。效果。此时。这个。建行。剃头。嗯。中这个用户我们直接说吧,用户B啊。增加。1万。对吧,几百元。那这肯定是不行的呀,对吧,啊出现。知道。数据。
04:00
这叫是不是数据不一致啊?对不对,这就出了问题了啊。那这个问题怎么解决?那我们的解决思路,解决思路这有了啊,给大家说。这思路是啊,让第一、二三步,让它具有原子性,什么叫原子性啊?要么全成功,要么全失败。即消息发送成功以后,必须要保证扣款成功。如果扣款失败,那么则回滚,呃,发送成功的消息。也就是说这里边是什么啊,这个这个思路啊,这个思路就是用什么事事物消息。这是。四就是15 15消息。安了,现在说到这个事物啊,呃,我们大家并不陌生。
05:00
对吧?呃,但这个事物呢,不同于我们以往的一个事物啊,这个事物大家想一下,就是我们这里边啊,确认要确认你这个消息发送成功。啊,确认消息发展需要谁在确认,我们的在确认。而你扣款。成功谁在确认?工商系统在确认?实际上是在两个不同的服务器上。这种确认操作。那你肯定不能用我们通常的这个事物,那这是什么事,就分布式事物。所以我们这里边啊,要使用的是分布式15。解决方案啊。就是。这里要使用。呃。喂。诶。分布式。十。
06:03
嗯。对吧,专门收当然啊,呃,我们看啊,这这这边这个这东西比较多,大家看。你看啊,我我这里边首先呃把解决思路要说了,然后这里边涉及到一些基础的东西啊,你像分布式事务是吧,事务消息什么这这这等等这些,然后FC模式啊三剑客,所以这里边涉及的东西比较多啊,咱们一点一点给大家说。呃,先把解决思路给大家说了,这里边儿涉及到的概念,我们一会儿在这儿详细给大家说啊,详细说。我们看这个图。这个图。呃,这个图里边啊,大家看我这边每一步也很清楚的给大家写了出来。首先。啊,这里边有个T,你看啊,那有个TM啊,有TMTC啊,TM是我们的事,你看事务管理器TM。
07:00
像事物协调剂TC事物协调剂。当然这些东西我们。一会讲三节课的时候要详细说,你先简单了解就行啊,知道这个概念就行了,我们一会一会说啊呃,所以首先第一步啊,我们的TM。呃,向TC,呃发送指令,什么指令啊,要开启全局事务,要开启全局事务。紧接着第二步,第二步你看第二步是我们的工行系统要发送消息M。就我们那个转账那个消息M啊,工行系统呃发送呃发发一个给B增款1万元的,呃,这个这个事务消息M给了谁,他是给了TC了。第三步。第三步在这儿呢,啊在这儿呢,那TC。会,你看TC会向发送这叫半事务消息啊,注意这里边有个叫半事务消息。
08:04
半数消息。Repair half。呃,注意啊,这个prepare这个我们这个啊,实际上呃,它是一个什么,是一个xa。X模式的啊,X模式是two PC的。当然关于这个two PC啊,Thirty PC,呃,这个你要不清楚,就是两阶段提交,三阶段提交,你要不清楚的话,那么你可以自己再从网上再查一些相关资料去学习一下啊,两阶段提交,三阶段提交,那么因为这个解决方案啊,它现在是基于sa模式的SC模式,我们一会儿也要详细给大家说啊。X模式的架构啊。那么。所以它是to PC的,To PC里边就有一个阶段,有commit阶段。那这是战士提交了一个什么叫办事消息?
09:01
体现半事物消息,哎,将将消息me,所谓的半事物消息其实主要就体现在这个。预提交啊。他不是不是真正的提交。这都什么意思,我呢,一会儿慢慢说了你就明白了啊,将消息M预提交到worker,所以这个啊,第三步TC啊。哎,向向这个brokeer发出一个什么预提交之类给了博ER。此时的建行系统,你注意你这个一提交系统就把这个消息M写到博了,但这个。这个这个消息啊,建行系统是看不到的。所以它叫什么?叫预提交。叫半数消息,所以它叫半数消息,我们一会儿要说半数消息对吧,哎,我这我这放到这儿了,消费者看不到,但我已经写进去了。然后。Broke会将预提交执行结果report给TC啊,他会上报这个会把它的预提交结果啊,上报给我们的TC。
10:08
那上报接你上报他就有两种结果,一个是成功,一个是失败是吧。紧接着这说了,如果预提交失败。如果预提失败,则TC会向工行系统。呃,不对啊,像在这儿会像谁会像TM啊。这是T。M提交失败的响应,拳击15结束。呃,这个啊。这个。他实际上是要把这个结果上报给我们的,TM上报给他,就像就像这这这一步一样上报给他。上爆胎以后,他会给出一个确认,全局性的确认指令。
11:03
啊,我们现在先不用管细节,反正是你这样上报了是吧,会向TM上报。呃,上报。上报的好。嗯。呃。预提交啊失败。是吧,一提交失败不太响应,然后这全局事务就结束,当然全局事务怎么就结束了,这结束肯定和TM有关系,你上报TM的,TM的会给他确认一个什么,呃,会给他发出一个确认指令,是叫global。啊,这个我们一会儿说啊。那我们现在说什么呢?说主逻辑就是成功了啊,如果预提交成功了,那么TC会。会调用工行系统的回调操作,注意啊,这里边儿有个回调操作,这个回调操作还是很重要的。
12:00
还是很重要的啊。会调工行系统的回调操作,去完成工行用户A的预扣款1万元的操作,也就是说他这啊,就你你这。呃,上报这个E提R,结果E提他成功了,成功以后紧接着作战。调用回调。就要回调完成扣款,在这儿完成也扣款,但这个扣款需要注意啊,这扣款它也是什么预扣款。去完成工行他的预扣款,看到了吧。予以扣款。完成预扣款,这都属于像半事务消息都属于半事务的啊啊预扣款预提交。然后呢,我们的工行系统会向TC发送预扣款执行的结果。哎,你你这个成功了没有是吧,你这个结果上报,这个结果肯定也是有成功和失败啊,也有成功和失败,我把这个结果给了TC。
13:04
呃,就是我们本地事务啊,执行的状态,这里边有出现一个概念叫本地事务啊,你注意我们这是一个叫全局事务,一个叫本地事务,你看全局事务。一个叫本地事物。哪儿呢,本地?一会这些概念我们都会给大家详细再再解释啊,全局事物就整体,这是一个全局事物,本地事物呢是这边一个全局事物是由N多个。这种。叫分支事物,你注意啊,由N多个分支事物构成。那么每一个分支事务,就它本身来说,诶我们从这儿来看,从工行系统来说,诶我这儿有个本地事务,有个全局事务,对吧,他对于这个博ER来说,他也有个本地事物,有个全局事务。明白吧?呃,工行系统向PC发送扣款成功的结果,即本地事务执行状态。
14:04
然后TC收到扣款成功结果以后上报给TM。你这样不是把结果发给我了吗?我会把这个上报扣款执行的结果给了TM这第七步。然后TM呢,会根据这个结果发出我们的全局。确认指令最终的全局事务的确认指令不一样了,这是全局的。这第八。这个指令呢?这个指令你注意啊,有。呃,这个指令有有可能会是三种情况。有可能会是三种情况啊。因为什么,因为这个结果啊扣款。扣款执行结果。存在三种可能性。呃。
15:00
嗯。嗯。Open。呃,执行结果。呃,陈。存在三种。可能性。哪三种?就是我们说的这。三就是三种状态,本地事物,本地事物的这个军营状态。他。是吧?和谁和他?这三种。这三种。呃,当然这个我们是可以看到,我们在代码里边也可以看到,因为它是本地事物啊,我们在这儿。这个叫。Local transaction status,大家看就这三种状态,大家看到没有,Local transaction status是吧?Commit message message和。
16:06
这三种状态啊。呃,那那那那这样吧。干脆这样写。我。什么事?是吧,呃,这个是这个是什么,呃,执行。本地。和这些成功。状态吧。执行。失败。这个啊,就不知道。不知道这个不知道啊,就是不确定不确定,呃,他是需要干嘛的。呃表示呃需要进行。回查,你注意需要进行回查,你确定本地事物。
17:07
执行。需要进行回查,这回查也很重要,我们一会儿专门给大家讲这个回查。还是比较比较麻烦的啊,要做做这个回查,就安诺啊,就他的三种。三种状态是吧,呃,就是。嗯。描述描述什么呀,呃,本地。竖直行。状态是吧,嗯。诶这三种啊啊,我我这儿就根据这三种,哎,如果如果你你这个预扣款啊,啊是成功的,就是这个这个状态,那么呃,PM就会像TCTM,你看TM就会像TC。发送什么?Commit。发送global之令,如果失败了,我就发送。
18:05
如果是unknown。如果动了,则会触发工行系统的本地事务。状态什么回查?对吧,回查操作。回查操作。回拆操作会将。呃,回查,呃回查操作会将回查结果,这回查结果就两个,呃,要么就是他,要么就是他就成功和失败。他或者他。啊,给给这个TC,有哥们说,那你回查一下海尔诺,海尔诺会继续再回查。继续回肠,只要你是诺,我就继续回肠,当然他不能一直再做这个回肠,那默尔是回查几次,15次。如果回查还回查不到结果,他就报错了。然后呢,TC将结果上报给TMTM会将这个会向TC发送最终确认指令。
19:07
也就是说这里边儿。最终我们这个确认指令啊,要么就是global,要么就是。对吧,哎,这是我们第八步,然后第九步,第九步这儿有,这儿有是吧,第九步。呃,这个这个这个。一了。我们。九。A点九八啊。是吧,是八啊,这个是九。就是九啊好,我们看第九步,第九步啊TC呃,在接收到指令后,会向broke与工行系统发出确认指令。TC接收到的啊,如果是global commit,那么brokeer会向工行系统发送bridge commit之类就是分支。
20:07
提交分支提交指令,这是我们的broke,就我们现在说的是这样啊。说到这。啊,你如果是global,我就给他NCH,如果你是global,我就是NCH。那么。而此时,ER中的消息M才会被建行系统看到。此时的工行用户A的扣款操作才能真正的去确认,也就是说啊,呃,你这如果是global commit,呃,我这儿就是好,这样的话,你原来是提交。那我现在就真的提交,然后我们的建行就能看到了,你这是预扣款。呃,我这样就跟你真正的完成了扣款。我们的用户就看到,哎,真的是扣款之前预扣款的时候,用户是看不到的啊,用户看到还是原来那个数。
21:04
明白吧,这是,那如果是global指定的,那就是branch。是吧,那就把把这些都给他回滚都撤销是吧,那你预预提交的啊,预提交的消息撤销是吧,然后你预扣款撤销回复。对不对,哎,这就是。我们说整个这个这个这个这个。这个解决方案啊,一个大一个一个很很很详细的一个思路了啊,其实大家想一下,我最终整个这个过程是为了确保什么。我问他确保什么,你看看你如果说我这一开,一旦开启了全局是我啊,你这如果预提交成功了。如果失败,如果你都失败了,我后边就不用看了。你成功了,我才进行下一步,下一步预扣款,预扣款你也成功了,那整个就成功了,肯定是我就成功了,如果你失败了,那同样失败,所以这就保证什么这两个操作,我们消息的这个投递。
22:12
和我们的扣款操作。是不是在一个事物里边,在这个全局事物里边。要成功都成功,要失败都失败。对不对,所以啊,我们。以上方案是吧,呃,就是为了呃。确保确保,呃,什么东西呢?呃,我们写上把这个这叫消息。呃,投递。与谁?与。扣款。操作。嗯。能够在呃一个事物中。要成功。
23:01
嗯。都。呃,有。一个失败的全部。是不是不管。是吧,哎,这是我们就为了确保这个东西啊嗯。呃,这里边儿啊,刚才我说了,他实际上是是谁是我们xa这种模式架构的啊,然后这里边儿可能如果咱们要要清楚什么是sa模式啊,这哥们可能会说了,老李你说的这个不对。怎么不对了?我给大家说啊,这个它不是一个典型的X模式。你说不对,是因为什么?是因为XC模式里边啊,各个就是我们这是全局事务,下边有分支事务,这些分支事务。之间的执行是并行的。
24:00
你注意啊。就是典型的啊,我们典型的xa模式里边它是。就是。并行的,或者说叫异步的。分支15是执行是异步的。但是我们现在这个是不是同步的,就是他执行完了他才执行啊。对不对,所以我们写上这么一个说明啊。呃,以上呃方案,呃,并不是一个典型的这个xa,呃。我是。对吧,啊,因为什么,因为xa。模式。X模式周长。分之。事物。是。等。而呃。而我们现在这个事,你注意这个这个方案就是事务消息的方案啊。而事物消息。而事物消息中事物消息。
25:04
二周。是。消息。预提交于。与这个。呃。玉。扣款。操作。呃,是。是同木的。对不对,是同步的啊,就是你得先搞完这个,他成功了才能搞这个。OK。呃,这是我们先通过这样一个呃应用场景,应用转账的应用场景,让大家呃先来了解一下这个事物消息。
我来说两句