diff --git a/src/storage/tx/ob_tx_data_functor.cpp b/src/storage/tx/ob_tx_data_functor.cpp index 7053384f7..a1f2af02c 100644 --- a/src/storage/tx/ob_tx_data_functor.cpp +++ b/src/storage/tx/ob_tx_data_functor.cpp @@ -97,7 +97,8 @@ int CheckRowLockedFunctor::operator() (const ObTxData &tx_data, ObTxCCCtx *tx_cc lock_state_.trans_version_ = commit_version; break; } - case ObTxData::RUNNING: { + case ObTxData::RUNNING: + case ObTxData::ELR_COMMIT: { if (read_tx_id_ == data_tx_id_) { // Case 2: data is during execution and it is owned by the checker, so // whether the lock is locked by the data depends on whether undo status @@ -121,6 +122,8 @@ int CheckRowLockedFunctor::operator() (const ObTxData &tx_data, ObTxCCCtx *tx_cc lock_state_.trans_version_.set_min(); break; default: + ret = OB_ERR_UNEXPECTED; + TRANS_LOG(ERROR, "wrong state", K(tx_data), KPC(tx_cc_ctx)); break; } } @@ -165,9 +168,14 @@ int GetTxStateWithSCNFunctor::operator()(const ObTxData &tx_data, ObTxCCCtx *tx_ // ts, so we return the abort state with 0 as txn version state_ = ObTxData::ABORT; trans_version_ = SCN::min_scn(); + } else if (ObTxData::ELR_COMMIT == state) { + // Case 5: data is elr committed and the required state is after the merge log + // ts, it means tx's state is completely decided so it must not be elr commit + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(ERROR, "unexpected state", K(ret), K(tx_data), KPC(tx_cc_ctx)); } else { ret = OB_ERR_UNEXPECTED; - STORAGE_LOG(WARN, "unexpected transaction state_", K(ret), K(tx_data)); + STORAGE_LOG(ERROR, "unexpected transaction state_", K(ret), K(tx_data)); } return ret; @@ -400,7 +408,7 @@ int ObCleanoutTxNodeOperation::operator()(const ObTxData &tx_data, ObTxCCCtx *tx } else { (void)tnode_.trans_abort(tx_data.end_scn_); } - } else if (ObTxData::RUNNING == state) { + } else if (ObTxData::RUNNING == state || ObTxData::ELR_COMMIT == state) { if (!tx_cc_ctx->prepare_version_.is_max()) { // Case 3: data is prepared, we also donot write back the prepare state }