use of info.xiancloud.core.message.ExceptionWithUnitResponse 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);
});
}
Aggregations