fescar

Fescar - RM AbstractDMLBaseExecu

2019-02-14  本文已影响14人  晴天哥_王志

开篇

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

 个人是认为抽取通用的内容放在一篇文章讲解完后可以针对每类Executor讲解特有的功能,这样能够有更好的理解。这篇文章讲解Executor的父类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);
        }
    }
}

说明:

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;

}

说明:

期待

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

上一篇 下一篇

猜你喜欢

热点阅读