Seata Server 1.5.2 源码学习( 二 )


文章插图
如果是AT模式,这里调用的就是ATCore#branchSessionLock()
ATCore#branchSessionLock()检查是否拿到锁了

Seata Server 1.5.2 源码学习

文章插图

Seata Server 1.5.2 源码学习

文章插图

Seata Server 1.5.2 源码学习

文章插图

Seata Server 1.5.2 源码学习

文章插图

Seata Server 1.5.2 源码学习

文章插图

Seata Server 1.5.2 源码学习

文章插图
具体每种锁的实现就不往下看了,挑其中一个看下,就RedisLocker吧
Seata Server 1.5.2 源码学习

文章插图
总之 , 分支注册的时候需要检查锁,拿到本次事务中所涉及的所有需要加锁的行的锁才能注册成功
所有行都加锁成功,分支注册才算成功,才会返回true
再回到AbstractCore#branchRegister(),整个方法是放在SessionHolder#lockAndExecute()中执行的
Seata Server 1.5.2 源码学习

文章插图

Seata Server 1.5.2 源码学习

文章插图
总结一下,分支注册:
  1. 创建一个BranchSession
  2. 加锁,获取所有行的锁
  3. 将BranchSession加到GlobalSession中
  4. 返回branchId

Seata Server 1.5.2 源码学习

文章插图
分支注册,创建BranchSession,获取全局锁成功后将branchSession加入globalSession
3. 提交全局事务
Seata Server 1.5.2 源码学习

文章插图

Seata Server 1.5.2 源码学习

文章插图
首先判断全局事务状态是否为begin,如果不是则不应该提交 。如果是,则将事务active置为false,释放全局锁,判断是否可以异步提交 。分支类型是AT的都可以异步提交 , 因此AT模式,默认是异步提交 。如果不能异步提交,则采取同步提交 。
3.1. 同步提交
Seata Server 1.5.2 源码学习

文章插图

Seata Server 1.5.2 源码学习

文章插图

Seata Server 1.5.2 源码学习

文章插图
遍历所有已注册的分支事务,向分支发送同步请求,告诉它全局事务开始提交了,不出意外的情况下返回分支状态是二阶段提交成功 。当所有分支都提交成功,则返回true,于是全局事务提交成功,返回全局事务状态为已提交 。如果有分支提交失败,则返回false,全局事务提交失败 , 返回全局状态为提交失败 。如果抛异常了,则会有定时任务稍后重试提交 。
3.2. 异步提交
Seata Server 1.5.2 源码学习

文章插图
异步提交只是将全局状态置为异步提交中,剩下的事情交给定时任务去执行
启动的时候调用了DefaultCoordinator#init()方法,启动定时任务
Seata Server 1.5.2 源码学习

文章插图

Seata Server 1.5.2 源码学习

文章插图
每次 , 定时任务执行前,要先获取一把分布式锁,这个锁是io.seata.core.store.DistributedLocker , 不是分支注册时的那把锁io.seata.core.lock.Locker
Seata Server 1.5.2 源码学习

文章插图

Seata Server 1.5.2 源码学习

文章插图
异步提交首先将全局状态设置为AsyncCommitting,返回返回全局状态Committed 。后台有定时任务扫描,找到所有状态为AsyncCommitting的全局事务 , 循环遍历 。对于每个全局事务提交 , 调用DefaultCore#doGlobalCommit(),遍历所有已注册的分支事务,向分支事务发请求,通知其提交事务,分支事务返回二阶段提交成功,表示该分支事务提交成功,当所有分支事务都二阶段提交成功 , 则全局事务提交成功 。
Seata Server 1.5.2 源码学习

文章插图
4. 回滚全局事务
Seata Server 1.5.2 源码学习

文章插图

Seata Server 1.5.2 源码学习

推荐阅读