diff --git a/source/dnode/mnode/impl/src/mndTrans.c b/source/dnode/mnode/impl/src/mndTrans.c index 0e4f4210fb..eb9df06894 100644 --- a/source/dnode/mnode/impl/src/mndTrans.c +++ b/source/dnode/mnode/impl/src/mndTrans.c @@ -857,6 +857,43 @@ int32_t mndTransCheckConflict(SMnode *pMnode, STrans *pTrans) { return 0; } +static bool mndTransActionsOfSameType(SArray *pActions) { + int32_t size = taosArrayGetSize(pActions); + ETrnAct lastActType = TRANS_ACTION_NULL; + bool same = true; + for (int32_t i = 0; i < size; ++i) { + STransAction *pAction = taosArrayGet(pActions, i); + if (i > 0) { + if (lastActType != pAction->actionType) { + same = false; + break; + } + } + lastActType = pAction->actionType; + } + return same; +} + +static int32_t mndTransCheckParallelActions(SMnode *pMnode, STrans *pTrans) { + if (pTrans->exec == TRN_EXEC_PARALLEL) { + if (mndTransActionsOfSameType(pTrans->redoActions) == false) { + terrno = TSDB_CODE_MND_TRANS_INVALID_STAGE; + mError("trans:%d, types of parallel redo actions are not the same", pTrans->id); + return -1; + } + + if (pTrans->policy == TRN_POLICY_ROLLBACK) { + if (mndTransActionsOfSameType(pTrans->undoActions) == false) { + terrno = TSDB_CODE_MND_TRANS_INVALID_STAGE; + mError("trans:%d, types of parallel undo actions are not the same", pTrans->id); + return -1; + } + } + } + + return 0; +} + int32_t mndTransPrepare(SMnode *pMnode, STrans *pTrans) { if (pTrans == NULL) return -1; @@ -864,6 +901,10 @@ int32_t mndTransPrepare(SMnode *pMnode, STrans *pTrans) { return -1; } + if (mndTransCheckParallelActions(pMnode, pTrans) != 0) { + return -1; + } + if (!pTrans->changeless && taosArrayGetSize(pTrans->commitActions) <= 0) { terrno = TSDB_CODE_MND_TRANS_CLOG_IS_NULL; mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr()); diff --git a/source/util/src/terror.c b/source/util/src/terror.c index 8723f227dd..187588f399 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -285,7 +285,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_MND_DNODE_IN_DROPPING, "Dnode in dropping sta // mnode-trans TAOS_DEFINE_ERROR(TSDB_CODE_MND_TRANS_ALREADY_EXIST, "Transaction already exists") TAOS_DEFINE_ERROR(TSDB_CODE_MND_TRANS_NOT_EXIST, "Transaction not exists") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_TRANS_INVALID_STAGE, "Invalid stage to kill") +TAOS_DEFINE_ERROR(TSDB_CODE_MND_TRANS_INVALID_STAGE, "Invalid transaction stage") TAOS_DEFINE_ERROR(TSDB_CODE_MND_TRANS_CONFLICT, "Conflict transaction not completed") TAOS_DEFINE_ERROR(TSDB_CODE_MND_TRANS_CLOG_IS_NULL, "Transaction commitlog is null") TAOS_DEFINE_ERROR(TSDB_CODE_MND_TRANS_NETWORK_UNAVAILL, "Unable to establish connection While execute transaction and will continue in the background")