您的位置:首页 > 其它

分布式事物 seata框架的学习 第一章 (GlobalTransactional注解源码解析(tm端))

2020-03-31 19:16 423 查看

GlobalTransactional 注解
这个全局注解 会被spring aop切入
下面看spring 对他做了什么

看到有一个interceptor 应该是 这个注解的代理
这个类实现了两个接口 ConfigurationChangeListener, MethodInterceptor
第一个 是 配置的监听 先不看 另一个 是springaop的接口
看到invoke方法
这个方法 是执行 GlobalTransactional的注解的方法 点进去看

这里面实现了一个 模版方法 先看 重写的方法
有 execute 和 getTransactionInfo
先看 execute 方法 就是直接执行了 被代理对象的调用方法
下面的 getTransactionInfo 是获取 他的 事务信息 里面 有几个 for循环 看到是 注解上的标注的 类的信息。有
NoRollbackRule
RollbackRule
接下来 看一下 这个注解上的类 我猜是 应该是 对应的 回滚策略


点进去看之后 是对应的回滚策略 当遇到什么类型的 异常后 应该捕获 回滚

接下来 进去 看一下他的模版方法transactionalTemplate

首先是 获取到 事务信息 不存在的话 回抛出异常
然后 是 判断 事物的传播类型
当是 notsupport 与 require 都会注销当前的 xid (顾名思义 挂起当前事物或者取消当前事物)

点击去看 unbind 方法


可以看到 是清除 xid 并返回

可以看到是继承了 两个类
一个是 fastthread 和 threadlocal threadllocal 都知道 是线程独占的变量
但是 fastthreadllocal 没见过 进去看看

文档介绍 是一个 通过数组去维护的一个 thread 线程私有变量 比散列要效率高 那哪里高呢

点进去看这个类 是一个 通过角标维护的 map 比散列 在已知角标的情况下 可以快速的获取值 比hash散列少了一步 hash值计算 与 hash碰撞导致的。从链表遍历(hashmap)
fastThreadlocal 详解:
FastThreadLocal详解链接
使用了非hash散列 在数据量大的时候 提高性能(不过jdk8 hashmap不是使用 红黑树了么)

接下来 继续看
下面的方法
not support 是解绑xid 然后执行被代理方法 返回
require new 是解绑 xid 继续向下运行
supports 是 直接向下运行 但是 会判断 是否有xid 为空 则会直接执行被代理方法 并返回
require 则执行执行
上面可见 通过判断传播类型的执行动作 主要在于 xid。这个xid表示是否还有事物
我们继续向下看:

这个是获取当前事物 或者创建 点进去看看具体做了啥



还是通过xid 判断当前是否有事物

这一步 是开始事物

这里面 有两个方法 除了begin方法之外 还有 beforbegin 与 afterbegin

是遍历了 currenthooks 是用来重写 hook接口 来做一些 事物开始前后的操作的(体现了开闭原则)


可以看到。有关于事物的每一步的方法执行 通过实现这个类 可以 做一些 记录等操作 比如写入到 elk 做一些统计
接下来 进去看看 begin方法 做了什么


begin方法开始 还是校验 当前是否为 调用者 然后 同时 开始事务的时候 要校验xid是否存在

下面的 manager.begin方法 是最终实际调用开始的方法 调用完之后 将事务状态改为 begin
下面 看看 具体的begin方法里面做了什么


同样的 还是异步通过rpc发送一个请求到 server 封装的request类型是 GlobalBeginRequest

这一步就不说了 正常的执行被代理方法

下面着重看一下 下面两个方法
第一个

这个方法从字面意思来看 就是提交事物了 进去看看做了啥 就做了提交 咋那么牛逼呢


Commit前后两个方法 还是跟上吗的 一样 用来 注册你的hook 在执行前后做一些你想做的事
着重看一下 commit方法

看到有两个实现类 看第一个 (我使用的 源码 第二个是测试 该方法用到的)

判断 角色 有 Participant 和 Launcher

参与者 与 执行者 的意思

如果是参与者 那就啥也不做 直接返回


第一个retry 是通过外部配置 获取 重试执行次数 如果 commit 跑异常 则决定重试 下面 进去看看 commit(xid) 方法

可以看到实现类 我们看tm包非测试的代码


是通过包装了一个 request 对象 通过rpc去发送请求 到 server

看到在往下看 是通过一个 ChannelFutere 异步发出一个请求 出去

同时这个方法 还能 loandbanace 发送到 server集群里面去

总结一下 这个方法 就是 异步的发送一个commit请求 到 server 然后接下来 看看 第二个方法

第二个

这个方法 看名称是 在异常抛出之后做的事 进去看看 做了啥

这个方法 会判断 txinfo 是否为空 以及 rollbackon 是否是 指定的exception
他会 遍历 其集成关系 判断 是否 是这个异常 以及这个异常的之类 都会进行回滚

接下来 看看 这个方法

这个方法 brfore 和 after 不多说了。看看 rollback方法吧


跟commit方法类似 也是异步的发送请求到 server
只不过 跟 commit不同 在于 这个封装的。GlobalRollbackRequest类型的对象

整个 commit 方法 (AT) 模式的就分析结束 可以看出 毕竟大厂出品 代码很清晰 接下来 会继续分析 server的代码 他是决定事务最终要执行动作的代码呢

  • 点赞
  • 收藏
  • 分享
  • 文章举报
挖掘地 发布了7 篇原创文章 · 获赞 6 · 访问量 440 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: