Seata源码分析——SessionManager

我们知道Seata服务端TC在全局事务中需要协调TM,RM分工干活,一个全局事务 GlobalSession

是由多个分支事务 BranchSession

组成的,那么TC端必须要对这些全局事务和分支事务进行管理,比如事务的创建、更新、删除…我们今天就来聊一聊Seata中的用来管理事务的 SessionManager。

  • 这里为什么叫SessionManager:有博客说Seata的中的事务也叫会话,会话管理器也叫事务管理器。我们就这样叫吧

事务管理器

SessionManager

SessionManager顾名思义它是用来管理事务的,是一个接口,我们来看它的继承关系:

Seata源码分析——SessionManager

SessionLifecycleListener

看字眼Lifecycle,说明在Seata中,事务是有生命周期的:从开始到结束,中间会有很多状态的变化SessionLifecycleListener,就是事务生命周期的监听器,使用了观察者模式,这个接口定义了一系列要监听的事件:

public interface SessionLifecycleListener {
    /**
     * 监听全局事务的开启,当处理全局事务开启请求时,会调用该方法
     */
    void onBegin(GlobalSession globalSession) throws TransactionException;

    /**
     * 监听全局事务对象GlobalSession的状态变化,只要是GlobalSession的状态发生变化,就会调用该方法
     */
    void onStatusChange(GlobalSession globalSession, GlobalStatus status) throws TransactionException;

    /**
     * 监听分支事务状态的变化,在处理分支状态报告请求时,会调用该方法
     */
    void onBranchStatusChange(GlobalSession globalSession, BranchSession branchSession, BranchStatus status)
        throws TransactionException;

    /**
     * 监听新的分支事务注册
     */
    void onAddBranch(GlobalSession globalSession, BranchSession branchSession) throws TransactionException;

    /**
     * 监听分支事务从全局事务对象中移除,
     * 当处理全局事务回滚请求全局事务提交请求时,都会有移除分支事务的动作,因此都会触发该方法
     */
    void onRemoveBranch(GlobalSession globalSession, BranchSession branchSession) throws TransactionException;

    /**
     * 监听全局事务关闭,也就是监听GlobalSession的close方法。
     * 在处理全局事务提交请求和全局事务回滚请求时,都会调用GlobalSession的close方法。
     */
    void onClose(GlobalSession globalSession) throws TransactionException;

    /**
     * 监听全局事务终止,也就是监听GlobalSession的end方法。
     * 当要求全局事务提交或者回滚时,无论最后成功与否,seata都会调用GlobalSession的end方法,因此都会触发onEnd
     */
    void onEnd(GlobalSession globalSession) throws TransactionException;
}

SessionManager则定义了GlobalSession状态发生变化时应该执行的动作方法

public interface SessionManager extends SessionLifecycleListener, Disposable {

    /**
     * 将全局事务对象添加到会话管理器中,当全局事务异步提交或者异步回滚时,都会调用该方法
     */
    void addGlobalSession(GlobalSession session) throws TransactionException;

    /**
     * 根据XID查找GlobalSession
     */
    GlobalSession findGlobalSession(String xid) ;

    /**
     * 不同的存储模式下,本方法和上面的方法实现不同,如果存储模式是file,则两个方法完全一致,
     * 如果存储模式是db,则上面的方法相当于调用findGlobalSession(xid, true)
     * 如果第二个参数为true,表示返回的GlobalSession对象中带有分支事务集合
     */
    GlobalSession findGlobalSession(String xid, boolean withBranchSessions);

    /**
     * 更新事务对象的状态
     */
    void updateGlobalSessionStatus(GlobalSession session, GlobalStatus status) throws TransactionException;

    /**
     * 从管理器中移除GlobalSession
     * 当异步提交重试超时时,会调用该方法
     */
    void removeGlobalSession(GlobalSession session) throws TransactionException;

    /**
     * 向GlobalSession中添加分支事务对象,当分支事务注册时,会调用该方法
     */
    void addBranchSession(GlobalSession globalSession, BranchSession session) throws TransactionException;

    /**
     * 更新分支事务状态
     */
    void updateBranchSessionStatus(BranchSession session, BranchStatus status) throws TransactionException;

    /**
     * 从全局事务中移除分支事务,当全局事务提交或者回滚时,会调用该方法
     */
    void removeBranchSession(GlobalSession globalSession, BranchSession session) throws TransactionException;

    /**
     * 返回所有的全局会话对象
     */
    Collection allSessions();

    /**
     * 根据条件查找符合要求的GlobalSession
     */
    List findGlobalSessions(SessionCondition condition);

    /**
     * 对全局事务对象加锁,当修改全局事务对象的状态时,都会加锁
     */
     T lockAndExecute(GlobalSession globalSession, GlobalSession.LockCallable lockCallable)
            throws TransactionException;
}

AbstractSessionManager

AbstractSessionManager是下一层的封装,它有三个实现类,分别对应三种存储模式:文件,数据库和Redis
它实现了SessionManager中定义的方法,还增加了一个重要的方法: writeSession,对Session管理的方法大多都直接或间接地调用了writeSession;我们简单来看一个:

    @Override
    public void removeGlobalSession(GlobalSession session) throws TransactionException {
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("MANAGER[{}] SESSION[{}] {}", name, session, LogOperation.GLOBAL_REMOVE);
        }
        writeSession(LogOperation.GLOBAL_REMOVE, session);
    }

AbstractSessionManager中还持有一个变量:事务存储管理器,也有三种实现,分别是文件,数据库和Redis。下面就继续分析它。

   /**
     * The Transaction store manager.

     */
    protected TransactionStoreManager transactionStoreManager;

事务存储管理器

事务管理器的作用是对Seata的事务进行管理,管理完了还得存储起来 。AbstractSessionManager这个类中还持有了TransactionStoreManager, 它是用来实现存储事务状态的。
下面我们以RedisTransactionStoreManager为例进行分析:

Seata源码分析——SessionManager

RedisTransactionStoreManager

Seata源码分析——SessionManager
可以看到有不少insert,delete的操作,说明这里就真正将事务信息存到Redis的逻辑了,我们挑一个来看一下:
 /**
     * Insert the global transaction.

     * @param globalTransactionDO
     * @return
     */
     // GlobalTransactionDO:要插入数据库的类,和global_table的字段是一一对应的
    private boolean insertGlobalTransactionDO(GlobalTransactionDO globalTransactionDO) {
        // 获取全局事务的键
        String globalKey = buildGlobalKeyByTransactionId(globalTransactionDO.getTransactionId());
        //使用了Jedis和Pipeline
        try (Jedis jedis = JedisPooledFactory.getJedisInstance(); Pipeline pipelined = jedis.pipelined()) {
            Date now = new Date();
            //构建要插入的DO
            globalTransactionDO.setGmtCreate(now);
            globalTransactionDO.setGmtModified(now);
            //通过pipeline执行
            pipelined.hmset(globalKey, BeanUtils.objectToMap(globalTransactionDO));
            pipelined.rpush(buildGlobalStatus(globalTransactionDO.getStatus()), globalTransactionDO.getXid());
            pipelined.sync();
            return true;
        } catch (Exception ex) {
            throw new RedisException(ex);
        }
    }

TO BE CONTINUE…

Original: https://www.cnblogs.com/leung-Gabriel/p/16322417.html
Author: 飞僧明天起飞
Title: Seata源码分析——SessionManager

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/592625/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 深入浅出分析 HashMap

    作者:炸鸡可乐原文出处:www.pzblog.cn 一、摘要 在集合系列的第一章,咱们了解到,Map的实现类有HashMap、LinkedHashMap、TreeMap、Ident…

    Java 2023年6月9日
    078
  • SpringBoot后端接口项目

    创建SpringBoot项目 项目目录 实体类 点击查看代码 package com.bai.entity; import com.baomidou.mybatisplus.ann…

    Java 2023年6月15日
    056
  • Nginx

    是一个高性能的 HTTP 和反向代理服务器,特点是占有内存少,并发能力强,事实上 nginx 的并发能力确实在同类型的网页服务器中表现较好。 Nginx 可以作为静态页面的 web…

    Java 2023年6月8日
    074
  • Linux

    1、关机命令 命令 说明 sync 将数据由内存同步到硬盘中 shutdown 关机 shutdown -h 10 10分钟后关机 shutdown -h now 立马关机 shu…

    Java 2023年6月15日
    063
  • mybatisPlus整理

    1.在启动类上面添加@MapperScan注解,扫描mapper包 1 @SpringBootApplication 2 @MapperScan("com.qiao.de…

    Java 2023年5月30日
    071
  • 韦东山视频第3课第2节_JNI_C调用JAVA_P【学习笔记】

    C调JAVA方法主要步骤如下: 一、C代码调用java的静态方法 Hello.java 1 public class Hello{ 2 public static void mai…

    Java 2023年5月29日
    099
  • Spring框架各Jar包说明

    常用Jar包说明: 这个jar 文件包含Spring 框架基本的核心工具类。Spring 其它组件要都要使用到这个包里的类,是其它组件的基本核心,当然你也可以在自己的应用系统中使用…

    Java 2023年5月30日
    065
  • 用户态与内核态,上下文的理解

    系统调用 为了安全应用程序无法直接调用的硬件的功能,而是将这些功能封装成特定的函数。当应用程序需要硬件功能时(例如读写文件),就需要进行系统调用。当进程进行系统调用后就从用户态装换…

    Java 2023年6月6日
    053
  • 反射加缓存,解决不同的业务下调用不同的实现

    根据前端传入不同的支付code,动态找到对应的支付方法,发起支付。我们先定义一个注解。 @Retention(RetentionPolicy.RUNTIME) @Target(El…

    Java 2023年6月14日
    061
  • WebSocket和Socket的区别_WebSocket和http的区别_WebScoket的长连接和http的长连接的区别_spring的单例bean是线程安全的吗_http请求头请求行请求体

    1 什么是WebSocket? WebSocket从满足基于Web的日益增长的实时通信需求应运而生,解决了客户端发起多个Http请求到服务器资源浏览器必须要在经过长时间的轮询问题,…

    Java 2023年5月30日
    063
  • Twikoo私有化部署教程–迁移腾讯云

    备份数据 私有化部署 创建容器 导入数据 重新配置twikoo面板设置 引入前端CDN Nginx https反代http 作者:小牛呼噜噜 | https://xiaoniuhu…

    Java 2023年6月15日
    078
  • Spring Boot2 核心功能

    1、文件类型 1、1 properties yml 控制台输出 单引号会将\n作为字符串输出 双引号会换行输出 单引号会转义,双引号不会转义 person: userName: &…

    Java 2023年6月13日
    076
  • Oracle用户、角色、权限

    一、Oracle权限 系统权限:系&#x…

    Java 2023年6月8日
    096
  • Java异常

    1.异常引入 package exception; @SuppressWarnings({"all"}) /** * @Author Blueshadow * …

    Java 2023年6月8日
    074
  • Spring IOCAOPBean

    Spring是一个轻量级的控制反转IOC和面向切面编程AOP的框架 Spring 自带 IoC(Inverse of Control:控制反转) 和 AOP(Aspect-Orie…

    Java 2023年6月5日
    078
  • 5.0.SpringBoot整合Kafka(工具安装ZK)

    我们在使用Kafka的时候,是依赖于zookeeper的,所以我们先安装好工具在去集成,这样之后也能直接跑起来。 我是Windows系统所以直接安装Win版本的zk和Kafka(M…

    Java 2023年6月9日
    065
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球