diff --git a/src/storage/tx/ob_trans_part_ctx.cpp b/src/storage/tx/ob_trans_part_ctx.cpp index 0d5f76c6d2..65a8a7ad0b 100644 --- a/src/storage/tx/ob_trans_part_ctx.cpp +++ b/src/storage/tx/ob_trans_part_ctx.cpp @@ -1000,8 +1000,14 @@ int ObPartTransCtx::replay_start_working_log(const SCN start_working_ts) return ret; } -// The txn is in the state between prepare and clear bool ObPartTransCtx::is_in_2pc_() const +{ + // The order is important if you use it without lock. + return is_2pc_logging_() || is_in_durable_2pc_(); +} + +// The txn is in the durable state between prepare and clear +bool ObPartTransCtx::is_in_durable_2pc_() const { ObTxState state = exec_info_.state_; return state >= ObTxState::PREPARE; @@ -2119,7 +2125,8 @@ int ObPartTransCtx::try_submit_next_log_(const bool for_freeze) { int ret = OB_SUCCESS; ObTxLogType log_type = ObTxLogType::UNKNOWN; - if (ObPartTransAction::COMMIT == part_trans_action_ && !is_2pc_logging_() && !is_in_2pc_() + if (ObPartTransAction::COMMIT == part_trans_action_ + && !is_in_2pc_() && !need_force_abort_()) { if (is_follower_()) { ret = OB_NOT_MASTER; diff --git a/src/storage/tx/ob_trans_part_ctx.h b/src/storage/tx/ob_trans_part_ctx.h index acb009a6fe..07b4e952b1 100644 --- a/src/storage/tx/ob_trans_part_ctx.h +++ b/src/storage/tx/ob_trans_part_ctx.h @@ -249,9 +249,14 @@ public: private: void default_init_(); int init_memtable_ctx_(const uint64_t tenant_id, const share::ObLSID &ls_id); - bool is_in_2pc_() const; + // Please use it carefully, because it only refer to the downstream_state_ + bool is_in_durable_2pc_() const; bool is_logging_() const; + // It is decided based on both durable 2pc state and on the fly logging. + // So it can be used safely at any time. + bool is_in_2pc_() const; + // force abort but not submit abort log bool need_force_abort_() const; // force abort but wait abort log_cb