一 、Seata编译
1、进行编译
二、启动源码
1、启动
更改 注册中心 和配置中心都是nacos
2、找入口
从上面我们可以看出Seata1.5.2就是一个springboot项目,我们可以从自动装配的角度来看,我们看一下seata-spring-boot-starter.1.5.2.jar里面的spring.factories,里面有对应的自动装配类SeataAutoConfiguration
在SeataAutoConfiguration我们找到对应注入的类GlobalTransactionScanner,通过名称我们应该推算出,他应该是对应@GlobalTransaction进行扫描,然后注入到容器
我们看他的继承关系发现,他是一个后置处理器,并且他继承AbstractAutoProxyCreator 这里面应该是创建代理的,他创建代理类是不是在wrapIfNecessary这个方法里面创建的?,好那我们来看一下
2.1 创建代理类
2.2 初始化 关键组件 TM RM
实现接口InitializingBean我们需要看他的对应方法afterPropertiesSet,对TM RM进行初始化
TM 和RM的通信都是通过Netty通信
3、发送请求进如核心方法
调用的时候一定会调用到我们的拦截器GlobalTransactionalInterceptor.invoke方法
处理全局事务
4、开启全局事务
4.1 客户端源码
开启事务这里的全局事务的默认超时时间是60s
发送请求获取全局事务Id
发送同步请求
这里客户端是在GlobalTransactionScanner 实现了接口InitializingBean
4.2 服务端处理
服务端处理我们这里有个核心类DefaultCoordinator
协调者我们看一下接口就有事务的处理
开启全局事务:
持久话数据:
-
获取全局事务Id
-
开启事务
进行数据持久化 重要接口TransactionStoreManager
这里对应的持久化的策略
核心新增更新等操作
5、执行业务逻辑
5.1 客户端执行
本地事务提交:业务数据和undo.log落库
注册分支事务、增加对应的锁
我们想我们在创建数据源的时候创建一个代理数据源 DataSourceProxy, 通过DataSourceProxy 我们可以获取代理链接ConnectionProxy,通过代理链接我们可以获取PreparedStatementProxy,那我们执行sql应该是在这里
key1: 设置手动提交
key2: 形成前后置镜像,这里的镜像执行形成,并没有插入数据库
key3:进行提交
这里面有commit和docommit,注册回滚等操作
key1: 注册分支事务
key2:插入日志
插入日志
上述插入日志但是并没有提交
5.2 服务端源码
注册分支事务、和分支锁
注册分支事务入口DefaultCoordinator
5.2.1获取全局事务
5.2.2、创建BranchSession
5.2.3、增加分支事务锁,防止数据被修改
行锁收集,为什么行锁是list,因为update的时候可能是多行
img
5.2.4、向全局session中添加分支session
5.2.5、出现异常释放锁
5.2.6: 返回分支会话的分支ID
6、服务间传递xid
6.1 Feign 传递xid
执行方法时候获取Request
6.2 RestTemplate进行调用
ClientHttpRequestInterceptor
7、提交事务
7.1 客户端
7.2 服务端
7.2.1 事务提交将事务改为异步提交中状态
7.2.2 定时任务处理异步提交的全局事务
定时任务处理对应的提交数据,这里每一秒执行一次
获取全局事务的分支事务,删除undolog
根据删除的分支事务的undolog的状态来处理,处理分支事务的数据和分支事务锁
重点我们分析一下key4: 删除分支事务释放全局锁
删除全局事务
7.2.3 分支事务客户端删除undolog
异步处理
8、事务回滚
8.1 客户端
8.2 服务端
客户端发送的请求是GlobalRollbackReqeust,那我们再服务端进行全文搜索
key1:事务回滚,先通过全局事xid找到全局事务和分支事务 1.先通过全局事务XID找到去global_table查询到全局事务对象 2.通过查询出来的xid对象去查询branch_talbe是否有分支事务,最后将这两个事务对象封装到GlobalSession中 这里传入的true代表全局事务和分支事务都查询出来,全局事务是一条数据,分支事务可能会多条是一个list
key2:真正的回滚逻辑
如果分支事务是在一阶段失败的,调用removeBranch,释放锁
branchRollback回滚分支事务,这里是server端,所以这里的分支事务的回滚是调用的远程进行回滚的而远程回滚就是使用的undo log日志表来回滚的
、、
根据调用客户端删除undolog的返回状态,来判断怎样处理
最后定时任务删除回滚对应的全局事务
8.3 客户端进行回滚
上面我们知道回滚我们发送请求为BranchRollbackRequest,那我们来到客户端端来全文搜索
在这里的undo方法中,会生成回滚sql,执行,然后删除undolog日志
9、查看回滚日志信息
navicat中查看中选择文本