Seata 1.5.2 源码学习(Client端)(seata.io)

  本篇文章为你整理了Seata 1.5.2 源码学习(Client端)(seata.io)的详细内容,包含有seata github seata.io seata1.4.2 seata1.4.0 Seata 1.5.2 源码学习(Client端),希望能帮助你了解 Seata 1.5.2 源码学习(Client端)。

  在上一篇中通过阅读Seata服务端的代码,我们了解到TC是如何处理来自客户端的请求的,今天这一篇一起来了解一下客户端是如何处理TC发过来的请求的。要想搞清楚这一点,还得从GlobalTransactionScanner说起。

  启动的时候,会调用GlobalTransactionScanner#initClient()方法,在initClient()中初始化TM和RM

  TM初始化,主要是注册各种处理器,最终构造一个处理器映射表,不再多说

  

HashMap Integer/*MessageType*/, Pair RemotingProcessor, ExecutorService processorTable = new HashMap (32);

 

  重点关注RM初始化

  RM初始化过程中,设置了 resourceManager 和 transactionMessageHandler,然后也是注册各种处理器,最终也是构造一个消息类型和对应的处理器的一个映射关系

  可以看到,图中上半部分是RM特有的,下半部分与TM初始化注册处理器类似

  然鹅,真正处理请求的还是靠调用各个处理器中的handler.onRequest()方法,于是问题的关键就很明显了,就在于handler

  1. ResourceManager

  在了解ResourceManager之前,让我们首先了解一下ResourceManagerInbound和ResourceManagerOutbound

  ResourceManagerInbound是处理接收到TC的请求的,是TC向RM发请求

  ResourceManagerOutbound是处理流出的消息的,是RM向TC发请求

  ResourceManager继承了二者,所以既负责向TC发请求,又负责接收从TC来的请求。

  还记得刚才在RMClient中是怎么获取ResourceManager的吗?是调用DefaultResourceManager.get()获取的

  DefaultResourceManager.get()得到的是一个单例DefaultResourceManager,创建DefaultResourceManager的时候会构建一个分支类型与ResourceManager的一个Map

  2. TransactionMessageHandler

  TransactionMessageHandler负责处理接收到的RPC消息

  前面在 RMClient 中通过 DefaultRMHandler.get() 获取 TransactionMessageHandler

  3. 消息处理

  RMClient#init()的时候new了一个RmNettyRemotingClient

  这里要记住,rmNettyRemotingClient的两个成员变量此时已经被赋值了:

  resourceManager是DefaultResourceManager,

  transactionMessageHandler是DefaultRMHandler

  RmNettyRemotingClient构造方法中调用父类AbstractNettyRemotingClient的构造方法

  可以看到,根据收到的RPC消息类型,从processorTable中获取对应的Processor,最后调用对应RemotingProcessor的process()方法进行处理消息

  RemotingProcessor的实现类很多,挑其中一个RmBranchCommitProcessor看一下

  真相大白,最终还是调DefaultRMHandler#handle()

  捋一下这个过程

  最后,补充一个,this为什么是DefaultRMHandler

  补充二:AbstractTransactionRequestToRM

  4. 分支事务提交(二阶段)

  交给AsyncWorker去执行

  可以看到:

  封装成一个Phase2Context对象,并将其放入队列中

  如果放入成功,则立即返回提交成功,后续交由定时任务执行

  如果放入失败,则主动触发定时任务先执行一次,以便腾出空间来,待执行完后,队列里面就有空间了,再将任务放入队列,等待下一次定时任务执行

  定时任务1秒执行一次,执行的时候将队列中的任务取出,然后循环遍历分段执行

  执行的过程就是删除对应事务的undo log

  如果过程中抛异常,则将任务再放回队列中

  所以,RM收到TC发的提交指令后,仅仅只是删除该事务的undo_log表记录

  5. 分支事务回滚(二阶段)

  与提交类似

  所以,回滚就是根据事务的undo_log进行回滚

  6. 总结

  1、启动时,自动代理数据源,应用GlobalTransactionalInterceptor,初始化TM和RM

  2、进入@GlobalTransactional业务方法时,TM向TC发请求申请开启全局事务,并获得全局事务ID

  3、业务方法调用远程服务接口完成业务处理

  4、RM执行本地逻辑,注册分支事务,获取全局锁,成功后提交本地事务并写入undo_log,本地事务提交成功后向TC报告分支事务

  5、TM发起全局事务提交请求,TC向所有已注册的RM发请求,让RM进行分支提交,删除本地undo_log

  6、若执行失败,TM发起全局事务回滚,TC向所有RM发请求,回滚分支事务,还原数据

  

  以上就是Seata 1.5.2 源码学习(Client端)(seata.io)的详细内容,想要了解更多 Seata 1.5.2 源码学习(Client端)的内容,请持续关注盛行IT软件开发工作室。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: