Fescar - RM AbstractDMLBaseExecutor介绍

本文深入探讨了数据库操作核心组件AbstractDMLBaseExecutor的实现原理,重点分析其在自动与非自动提交模式下如何执行事务,以及如何通过beforeImage和afterImage方法维护数据一致性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

开篇

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值