美文网首页fescar
Fescar - RM AbstractDMLBaseExecu

Fescar - RM AbstractDMLBaseExecu

作者: 晴天哥_王志 | 来源:发表于2019-02-14 23:22 被阅读14次

    开篇

     这篇文章的目的是讲解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 - RM AbstractDMLBaseExecu

        本文链接:https://www.haomeiwen.com/subject/rytueqtx.html