Search in sources :

Example 1 with ISingleTableAction

use of info.xiancloud.dao.core.action.ISingleTableAction in project xian by happyyangyuan.

the class DaoUnit method execute.

/**
 * @param request the request object.
 * @param handler the unit response consumer, this handler must be executed asynchronously.
 */
@Override
public final void execute(UnitRequest request, Handler<UnitResponse> handler) {
    final SqlAction[] sqlActions = getActions();
    for (SqlAction sqlAction : sqlActions) {
        if (sqlAction instanceof ISingleTableAction) {
            TableMetaCache.makeSureCache(((ISingleTableAction) sqlAction).getTableName());
        }
    }
    bareError(request);
    final boolean readOnly = readOnly(sqlActions, request) || request.getContext().isReadyOnly();
    final AtomicBoolean transactional = new AtomicBoolean(false);
    final UnitResponse[] tempUnitResponse = new UnitResponse[] { null };
    final XianTransaction[] tempTransaction = new XianTransaction[] { null };
    TransactionFactory.getTransaction(request.getContext().getMsgId(), readOnly).flatMap(transaction -> {
        tempTransaction[0] = transaction;
        transactional.set(isTransactional(sqlActions, transaction));
        if (transactional.get()) {
            // business layer has begun the transaction, here we reentrant it.
            return transaction.begin().toSingle(() -> transaction);
        } else {
            // if transaction is not begun by business layer, here we do not begin the transaction
            return Single.just(transaction);
        }
    }).flatMap(transaction -> Flowable.fromArray(sqlActions).concatMapSingle(action -> action.execute(this, request.getArgMap(), transaction.getConnection(), request.getContext().getMsgId())).reduce(UnitResponse.succeededSingleton(), (unitResponse, unitResponse2) -> {
        if (unitResponse2.succeeded()) {
            return unitResponse2;
        } else {
            throw new ExceptionWithUnitResponse(unitResponse2);
        }
    }).flatMapCompletable(unitResponse -> {
        tempUnitResponse[0] = unitResponse;
        if (transactional.get()) {
            return transaction.commit();
        } else {
            return Completable.complete();
        }
    }).toSingle(() -> tempUnitResponse[0]).onErrorResumeNext(error -> {
        ExceptionWithUnitResponse exceptionWithUnitResponse;
        if (error instanceof ExceptionWithUnitResponse) {
            exceptionWithUnitResponse = (ExceptionWithUnitResponse) error;
        } else {
            LOG.error(error);
            exceptionWithUnitResponse = new ExceptionWithUnitResponse(UnitResponse.createException(error));
        }
        if (transactional.get()) {
            // if transaction is begun then rollback here
            return transaction.rollback().andThen(Single.just(exceptionWithUnitResponse.getUnitResponse()));
        } else {
            // if no transaction is begun, no need transaction rollback.
            return Single.just(exceptionWithUnitResponse.getUnitResponse());
        }
    })).doFinally(() -> tempTransaction[0].close().subscribe()).subscribe(unitResponse -> {
        unitResponse.getContext().setMsgId(request.getContext().getMsgId());
        handler.handle(unitResponse);
    }, error -> {
        LOG.error(error);
        UnitResponse errorResponse = UnitResponse.createException(error);
        errorResponse.getContext().setMsgId(request.getContext().getMsgId());
        handler.handle(errorResponse);
    });
}
Also used : XianConnection(info.xiancloud.dao.core.connection.XianConnection) TableMetaCache(info.xiancloud.dao.core.utils.TableMetaCache) TransactionFactory(info.xiancloud.dao.core.transaction.TransactionFactory) Unit(info.xiancloud.core.Unit) UnitRequest(info.xiancloud.core.message.UnitRequest) StringUtil(info.xiancloud.core.util.StringUtil) AbstractSqlAction(info.xiancloud.dao.core.action.AbstractSqlAction) Completable(io.reactivex.Completable) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) UnitResponse(info.xiancloud.core.message.UnitResponse) SqlAction(info.xiancloud.dao.core.action.SqlAction) Handler(info.xiancloud.core.Handler) Single(io.reactivex.Single) ISingleTableAction(info.xiancloud.dao.core.action.ISingleTableAction) Input(info.xiancloud.core.Input) ISelect(info.xiancloud.dao.core.action.select.ISelect) Flowable(io.reactivex.Flowable) PoolFactory(info.xiancloud.dao.core.pool.PoolFactory) Map(java.util.Map) LOG(info.xiancloud.core.util.LOG) XianTransaction(info.xiancloud.dao.core.transaction.XianTransaction) ExceptionWithUnitResponse(info.xiancloud.core.message.ExceptionWithUnitResponse) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) UnitResponse(info.xiancloud.core.message.UnitResponse) ExceptionWithUnitResponse(info.xiancloud.core.message.ExceptionWithUnitResponse) ISingleTableAction(info.xiancloud.dao.core.action.ISingleTableAction) XianTransaction(info.xiancloud.dao.core.transaction.XianTransaction) ExceptionWithUnitResponse(info.xiancloud.core.message.ExceptionWithUnitResponse) AbstractSqlAction(info.xiancloud.dao.core.action.AbstractSqlAction) SqlAction(info.xiancloud.dao.core.action.SqlAction)

Aggregations

Handler (info.xiancloud.core.Handler)1 Input (info.xiancloud.core.Input)1 Unit (info.xiancloud.core.Unit)1 ExceptionWithUnitResponse (info.xiancloud.core.message.ExceptionWithUnitResponse)1 UnitRequest (info.xiancloud.core.message.UnitRequest)1 UnitResponse (info.xiancloud.core.message.UnitResponse)1 LOG (info.xiancloud.core.util.LOG)1 StringUtil (info.xiancloud.core.util.StringUtil)1 AbstractSqlAction (info.xiancloud.dao.core.action.AbstractSqlAction)1 ISingleTableAction (info.xiancloud.dao.core.action.ISingleTableAction)1 SqlAction (info.xiancloud.dao.core.action.SqlAction)1 ISelect (info.xiancloud.dao.core.action.select.ISelect)1 XianConnection (info.xiancloud.dao.core.connection.XianConnection)1 PoolFactory (info.xiancloud.dao.core.pool.PoolFactory)1 TransactionFactory (info.xiancloud.dao.core.transaction.TransactionFactory)1 XianTransaction (info.xiancloud.dao.core.transaction.XianTransaction)1 TableMetaCache (info.xiancloud.dao.core.utils.TableMetaCache)1 Completable (io.reactivex.Completable)1 Flowable (io.reactivex.Flowable)1 Single (io.reactivex.Single)1