Seata Server 1.5.2 源码学习( 二 )


  • 给GlobalSession添加一个监听器SessionManager
  • session.begin()

  • Seata Server 1.5.2 源码学习

    文章插图
    开启事务,创建一个全局事务,如果是seata.store.mode=db的话,向global_table表插入一条记录
    2. 分支事务注册
    Seata Server 1.5.2 源码学习

    文章插图

    Seata Server 1.5.2 源码学习

    文章插图
    DefaultCore#branchRegister()
    Seata Server 1.5.2 源码学习

    文章插图

    Seata Server 1.5.2 源码学习

    文章插图

    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,全局事务提交失败,返回全局状态为提交失败 。如果抛异常了,则会有定时任务稍后重试提交 。

    经验总结扩展阅读