分布式事务Seata源码分析

211 阅读4分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第14天,点击查看活动详情

1.Seata调试环境搭建

源码拉取

源码: github.com/seata/seata…

官方Demo: github.com/seata/seata…

源码编译

seata编译版本: checkout tag v1.4.0

源码编译问题:

seata源码导入到idea中第一次启动server端的时候,编译会报错如下:

image.png

问题原因:缺少protobuf编译的java文件

解决方案:idea安装protobuf support插件,重启idea。

插件下载地址: github.com/ksprojects/…

注意idea版本不能高于插件版本

image.png

通过protobuf:compile编译seata-serializer包

image.png

执行之后就会生成java代码

image.png

配置db存储模式

修改resources下的file.conf,修改store.mode="db",修改store.db相关配置

image.png

启动Seata TC Server服务

先启动nacos server服务,然后找到server模块下io.seata.server.Server.java,执行main方法启动

image.png

2. 核心接口和类

ResourceManager

ResourceManager是seata的重要组件之一,RM负责管理分支数据资源的事务。

image.png

AbstractResourceManager实现ResourceManager提供模板方法。DefaultResourceManager适配所有的ResourceManager,所有方法调用都委派给对应负责的ResourceManager处理。

image.png

DataSourceManager

此为AT模式核心管理器,DataSourceManager继承AbstractResourceManager,管理数据库Resouce的注册,提交以及回滚等

image.png

AsyncWorker DataSourceManager事务提交委派给AsyncWorker进行提交的,因为都成功了,无需回滚成功的数据,只需要删除生成的操作日志就行,采用异步方式,提高效率。

AsyncWorker#doBranchCommits
> UndoLogManagerFactory.getUndoLogManager(dataSourceProxy.getDbType())
    .batchDeleteUndoLog(xids, branchIds, conn)

UndoLogManager

image.png

TransactionManager

image.png

image.png

DefaultTransactionManager

TransactionManagerHolder为创建单例TransactionManager的工厂,可以使用EnhancedServiceLoader的spi机制加载用户自定义的类,默认为DefaultTransactionManager。

image.png

GlobalTransaction

GlobalTransaction接口提供给用户开启事务,提交,回滚,获取状态等方法。

image.png

DefaultGlobalTransaction

DefaultGlobalTransaction是GlobalTransaction接口的默认实现,它持有TransactionManager对象,默认开启事务超时时间为60秒,默认名称为default,因为调用者的业务方法可能多重嵌套创建多个GlobalTransaction对象开启事务方法,因此GlobalTransaction有GlobalTransactionRole角色属性,只有Launcher角色的才有开启、提交、回滚事务的权利。

GlobalTransactionContext

GlobalTransactionContext为操作GlobalTransaction的工具类,提供创建新的GlobalTransaction,获取当前线程有的GlobalTransaction等方法。

GlobalTransactionScanner

GlobalTransactionScanner继承AbstractAutoProxyCreator类,即实现了SmartInstantiationAwareBeanPostProcessor接口,会在spring容器启动初始化bean的时候,对bean进行代理操作。wrapIfNecessary为继承父类代理bean的核心方法,如果用户配置了service.disableGlobalTransaction为false属性则注解不生效直接返回,否则对GlobalTransactional或GlobalLock的方法进行拦截代理。

GlobalTransactionalInterceptor

GlobalTransactionalInterceptor实现aop的MethodInterceptor接口,对有@GlobalTransactional或GlobalLock注解的方法进行代理。

TransactionalTemplate

TransactionalTemplate模板类提供了一个开启事务,执行业务,成功提交和失败回滚的模板方法execute(TransactionalExecutor business)。

image.png

Resource

Resource能被ResourceManager管理并且能够关联GlobalTransaction。

image.png

DataSourceProxy

DataSourceProxy实现Resource接口,BranchType为AT自动模式。它继承AbstractDataSourceProxy代理类,所有的DataSource相关的方法调用传入的targetDataSource代理类的方法,除了创建connection方法为创建ConnectionProxy代理类。对象初始化时获取连接的jdbcUrl作为resourceId,并注册至DefaultResourceManager进行管理。同时还提供获取原始连接不被代理的getPlainConnection方法。

image.png

ConnectionProxy

private void doCommit() throws SQLException {
    if (context.inGlobalTransaction()) {
        processGlobalTransactionCommit();
    } else if (context.isGlobalLockRequire()) {
        processLocalCommitWithGlobalLocks();
    } else {
        targetConnection.commit();
    }
}
private void processGlobalTransactionCommit() throws SQLException {
    try {
        register();
    } catch (TransactionException e) {
        recognizeLockKeyConflictException(e, context.buildLockKeys());
    }
    try {
        UndoLogManagerFactory.getUndoLogManager(this.getDbType()).flushUndoLogs(this);
        targetConnection.commit();
    } catch (Throwable ex) {
        LOGGER.error("process connectionProxy commit error: {}", ex.getMessage(), ex);
        report(false);
        throw new SQLException(ex);
    }
    if (IS_REPORT_SUCCESS_ENABLE) {
        report(true);
    }
    context.reset();
}

ExecuteTemplate

ExecuteTemplate为具体statement的execute,executeQuery和executeUpdate执行提供模板方法

Executor

image.png

SQLRecognizer

SQLRecognizer识别sql类型,获取表名,表别名以及原生sql

UndoExecutorFactory

UndoExecutorFactory根据sqlType生成对应的AbstractUndoExecutor。

UndoExecutor为生成执行undoSql的核心。如果全局事务回滚,它会根据beforeImage和afterImage以及sql类型生成对应的反向sql执行回滚数据,并添加脏数据校验机制,使回滚数据更加可靠。

DefaultCoordinator

DefaultCoordinator即为TC,全局事务默认的事务协调器。它继承AbstractTCInboundHandler接口,为TC接收RM和TM的request请求数据,是进行相应处理的处理器。实现TransactionMessageHandler接口,去处理收到的RPC信息。实现ResourceManagerInbound接口,发送至RM的branchCommit,branchRollback请求。

image.png

image.png

Core

Core接口为seata处理全球事务协调器TC的核心处理器,它继承ResourceManagerOutbound接口,接受来自RM的rpc网络请求(branchRegister,branchReport,lockQuery)。同时继承TransactionManager接口,接受来自TM的rpc网络请求(begin,commit,rollback,getStatus),另外提供提供3个接口方法。

image.png

image.png

ATCore

image.png

GlobalSession

GlobalSession是seata协调器DefaultCoordinator管理维护的重要部件,当用户开启全局分布式事务,TM调用begin方法请求至TC,TC则创建GlobalSession实例对象,返回唯一的xid。它实现SessionLifecycle接口,提供begin,changeStatus,changeBranchStatus,addBranch,removeBranch等操作session和branchSession的方法。

BranchSession

BranchSession为分支session,管理分支数据,受globalSession统一调度管理,它的lock和unlock方法由lockManger实现。

LockManager

DefaultLockManager是LockManager的默认实现,它获取branchSession的lockKey,转换成List,委派Locker进行处理。

image.png

Locker

Locker接口提供根据行数据获取锁,释放锁,是否锁住和清除所有锁的方法。

image.png

3. 源码分析

www.processon.com/view/link/6…

www.processon.com/view/link/5…