Fescar - RM AbstractDMLBaseExecutor介绍

简介: 开篇 这篇文章的目的是讲解RM Executor模块当中一些通用的方法,这些方法在各个Executor的父类当中实现的,各个子类Executor模块都会复用,因此抽取出来统一的进行讲解。 个人是认为抽取通用的内容放在一篇文章讲解完后可以针对每类Executor讲解特有的功能,这样能够有更好的理解。

开篇

 这篇文章的目的是讲解RM Executor模块当中一些通用的方法,这些方法在各个Executor的父类当中实现的,各个子类Executor模块都会复用,因此抽取出来统一的进行讲解。

 个人是认为抽取通用的内容放在一篇文章讲解完后可以针对每类Executor讲解特有的功能,这样能够有更好的理解。这篇文章讲解Executor的父类AbstractDMLBaseExecutor。


类依赖图


说明:

  • 着重讲解AbstractDMLBaseExecutor抽象父类。


AbstractDMLBaseExecutor方法介绍

public abstract class AbstractDMLBaseExecutor<T, S extends Statement> 
  extends BaseTransactionalExecutor<T, S> {

    public AbstractDMLBaseExecutor(StatementProxy<S> statementProxy, 
     StatementCallback<T, S> statementCallback, SQLRecognizer sqlRecognizer) {
        super(statementProxy, statementCallback, sqlRecognizer);
    }

    @Override
    public T doExecute(Object... args) throws Throwable {
        AbstractConnectionProxy connectionProxy = 
                     statementProxy.getConnectionProxy();
        if (connectionProxy.getAutoCommit()) {
            return executeAutoCommitTrue(args);
        } else {
            return executeAutoCommitFalse(args);
        }
    }
}

说明:

  • AbstractDMLBaseExecutor的doExecute内部执行事务操作。
  • executeAutoCommitTrue()执行事务自动提交的操作。
  • executeAutoCommitFalse()执行事务不自动提交的操作。


public abstract class AbstractDMLBaseExecutor<T, S extends Statement> 
  extends BaseTransactionalExecutor<T, S> {

    protected T executeAutoCommitFalse(Object[] args) throws Throwable {
        // 准备执行前镜像
        TableRecords beforeImage = beforeImage();

        // 执行事务,内部调用statement.execute执行
        T result = statementCallback.execute(
           statementProxy.getTargetStatement(), args);

        // 准备执行后镜像
        TableRecords afterImage = afterImage(beforeImage);

        // 准备回滚日志
        statementProxy.getConnectionProxy().prepareUndoLog(
             sqlRecognizer.getSQLType(), sqlRecognizer.getTableName(), 
             beforeImage, afterImage);

        return result;
    }

    protected T executeAutoCommitTrue(Object[] args) throws Throwable {
        T result = null;
        AbstractConnectionProxy connectionProxy = 
                       statementProxy.getConnectionProxy();
        LockRetryController lockRetryController = new LockRetryController();
        try {
            connectionProxy.setAutoCommit(false);
            while (true) {
                try {
                    result = executeAutoCommitFalse(args);
                    connectionProxy.commit();
                    break;
                } catch (LockConflictException lockConflict) {
                    lockRetryController.sleep(lockConflict);
                }
            }

        } catch (Exception e) {
            throw e;
        } finally {
            connectionProxy.setAutoCommit(true);
        }
        return result;
    }

    protected abstract TableRecords beforeImage() throws SQLException;

    protected abstract TableRecords afterImage(TableRecords beforeImage) 
       throws SQLException;

}

说明:

  • 自动提交内部executeAutoCommitTrue调用的非自动提交executeAutoCommitFalse。
  • executeAutoCommitFalse按照准备执行前镜像、执行本地事务、准备执行后镜像,准备回滚日志。
  • statementCallback.execute最终执行StatementProxy和PreparedStatementProxy的statement.execute()完成事务操作。
  • statementProxy.getConnectionProxy().prepareUndoLog()负责准备回滚日志。


期待

 后续我们会将几类Executor的beforeImage()和afterImage()方法进行详细讲解。

目录
相关文章
|
Java Nacos Docker
Docker安装Seata分布式事务
Docker安装Seata分布式事务
Docker安装Seata分布式事务
RM在seata AT模式中如何实现分支事务提交或回滚
RM在seata AT模式中如何实现分支事务提交或回滚
379 0
|
Java 微服务 Spring
Seata 客户端需要同时启动 RM 和 TM 吗?
在分析启动部分源码时,我发现 GlobalTransactionScanner 会同时启动 RM 和 TM client,但根据 Seata 的设计来看,TM 负责全局事务的操作,如果一个服务中不需要开启全局事务,此时是不需要启动 TM client的,也就是说项目中如果没有全局事务注解,此时是不是就不需要初始化 TM client 了,因为不是每个微服务,都需要 GlobalTransactional,它此时仅仅作为一个 RM client 而已。
115 0
Seata 客户端需要同时启动 RM 和 TM 吗?
|
Shell Nacos 微服务
seata夸服务器服务注册RM失败问题
seata夸服务器服务注册RM失败问题
565 0
|
FESCAR SQL
Fescar - RM SelectForUpdateExecutor介绍
开篇  这篇文章的目的是讲解RM Executor模块当中一些通用的方法,这些方法在各个Executor的父类当中实现的,各个子类Executor模块都会复用,因此抽取出来统一的进行讲解。  个人是认为抽取通用的内容放在一篇文章讲解完后可以针对每类Executor讲解特有的功能,这样能够有更好的理解。
1146 0
|
SQL FESCAR 安全
Fescar - RM UpdateExecutor介绍
开篇  这篇文章的目的是讲解RM Executor模块当中一些通用的方法,这些方法在各个Executor的父类当中实现的,各个子类Executor模块都会复用,因此抽取出来统一的进行讲解。  个人是认为抽取通用的内容放在一篇文章讲解完后可以针对每类Executor讲解特有的功能,这样能够有更好的理解。
1087 0
|
SQL FESCAR
Fescar - RM DeleteExecutor介绍
开篇  这篇文章的目的是讲解RM Executor模块当中一些通用的方法,这些方法在各个Executor的父类当中实现的,各个子类Executor模块都会复用,因此抽取出来统一的进行讲解。  个人是认为抽取通用的内容放在一篇文章讲解完后可以针对每类Executor讲解特有的功能,这样能够有更好的理解。
1061 0
|
FESCAR SQL druid
Fescar - RM InsertExecutor介绍
开篇  这篇文章的目的是讲解RM Executor模块当中一些通用的方法,这些方法在各个Executor的父类当中实现的,各个子类Executor模块都会复用,因此抽取出来统一的进行讲解。  个人是认为抽取通用的内容放在一篇文章讲解完后可以针对每类Executor讲解特有的功能,这样能够有更好的理解。
1304 0
|
SQL FESCAR 数据库
Fescar - RM BaseTransactionalExecutor介绍
开篇  这篇文章的目的是讲解RM Executor模块当中一些通用的方法,这些方法在各个Executor的父类当中实现的,各个子类Executor模块都会复用,因此抽取出来统一的进行讲解。  个人是认为抽取通用的内容放在一篇文章讲解完后可以针对每类Executor讲解特有的功能,这样能够有更好的理解。
1106 0
|
SQL FESCAR
Fescar - RM ExecuteTemplate介绍
开篇  这篇文章的目的是介绍Fescar的RM模块中的ExecuteTemplate的代码,ExecuteTemplate作为StatementProxy当中真正执行SQL操作的模块,在Proxy和Executor的串联中起到承上启下的作用。
1134 0