Fescar - RM AbstractDMLBaseExecutor介绍

开篇

 这篇文章的目的是讲解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()方法进行详细讲解。


Fescar源码分析连载

Fescar 源码解析系列

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 1.java基本数据类型 java一共8个基本数据类型 byte 1字节(1byte = 8 bit)sh...
    陽_young阅读 6,445评论 3 20
  • 1、面向对象的特征有哪些方面? 答:面向对象的特征主要有以下几个方面: -- 抽象:抽象是将一类对象的共同特征总结...
    ccc_74bd阅读 4,572评论 0 1
  • --- layout: post title: "如果有人问你关系型数据库的原理,叫他看这篇文章(转)" date...
    蓝坠星阅读 4,294评论 0 3
  • 因为有了人海 所以遇见你是最美丽的意外 都希望在最好的年华遇见一个人 可往往是遇见了一个人 才迎来最好的年华 我一...
    方家的花姑娘阅读 2,990评论 0 6
  • 六盘水今日天气:白天多云,夜间小雨,气温1~16度,空气质量指数58(良)。 大家都知道饮食的金字塔...
    这样生活添色彩张洁阅读 1,580评论 0 2

友情链接更多精彩内容