首页IT科技seata配置中心(Seata 1.5.2 源码学习(Client端))

seata配置中心(Seata 1.5.2 源码学习(Client端))

时间2025-09-18 17:35:34分类IT科技浏览6361
导读:在上一篇中通过阅读Seata服务端的代码,我们了解到TC是如何处理来自客户端的请求的,今天这一篇一起来了解一下客户端是如何处理TC发过来的请求的。要想搞清楚这一点,还得从GlobalTransactionScanner说起。...

在上一篇中通过阅读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发请求,回滚分支事务                     ,还原数据

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
二叉搜索树的创建及遍历(每日算法之二叉搜索树与双向链表) 内核dtb(驱动开发:内核封装TDI网络通信接口)