This is an automated email from the ASF dual-hosted git repository.

morningman pushed a commit to branch branch-4.0
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-4.0 by this push:
     new e530e9f8b44 branch-4.0: [fix](transaction) avoid aborting newer 
same-label transactions (#65619)
e530e9f8b44 is described below

commit e530e9f8b443b481b13ae766b84ef55acac41206
Author: hui lai <[email protected]>
AuthorDate: Fri Jul 17 12:58:17 2026 +0800

    branch-4.0: [fix](transaction) avoid aborting newer same-label transactions 
(#65619)
    
    pick https://github.com/apache/doris/pull/64939
---
 be/src/cloud/cloud_meta_mgr.cpp       |  7 ++--
 be/test/cloud/cloud_meta_mgr_test.cpp | 62 +++++++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+), 3 deletions(-)

diff --git a/be/src/cloud/cloud_meta_mgr.cpp b/be/src/cloud/cloud_meta_mgr.cpp
index e98e05bd8ba..7bfc5705b81 100644
--- a/be/src/cloud/cloud_meta_mgr.cpp
+++ b/be/src/cloud/cloud_meta_mgr.cpp
@@ -1484,16 +1484,17 @@ Status CloudMetaMgr::abort_txn(const StreamLoadContext& 
ctx) {
     AbortTxnResponse res;
     req.set_cloud_unique_id(config::cloud_unique_id);
     req.set_reason(std::string(ctx.status.msg().substr(0, 1024)));
-    if (ctx.db_id > 0 && !ctx.label.empty()) {
+    if (ctx.txn_id > 0) {
+        req.set_txn_id(ctx.txn_id);
+    } else if (ctx.db_id > 0 && !ctx.label.empty()) {
         req.set_db_id(ctx.db_id);
         req.set_label(ctx.label);
-    } else if (ctx.txn_id > 0) {
-        req.set_txn_id(ctx.txn_id);
     } else {
         LOG(WARNING) << "failed abort txn, with illegal input, db_id=" << 
ctx.db_id
                      << " txn_id=" << ctx.txn_id << " label=" << ctx.label;
         return Status::InternalError<false>("failed to abort txn");
     }
+    TEST_SYNC_POINT_RETURN_WITH_VALUE("CloudMetaMgr::abort_txn.before_rpc", 
Status::OK(), &req);
     return retry_rpc("abort txn", req, &res, &MetaService_Stub::abort_txn);
 }
 
diff --git a/be/test/cloud/cloud_meta_mgr_test.cpp 
b/be/test/cloud/cloud_meta_mgr_test.cpp
index 3f2f7fe4ef6..aec1a5f21d8 100644
--- a/be/test/cloud/cloud_meta_mgr_test.cpp
+++ b/be/test/cloud/cloud_meta_mgr_test.cpp
@@ -32,6 +32,7 @@
 #include "olap/rowset/rowset_factory.h"
 #include "olap/rowset/rowset_meta.h"
 #include "olap/tablet_meta.h"
+#include "runtime/stream_load/stream_load_context.h"
 #include "util/uid_util.h"
 
 namespace doris {
@@ -43,6 +44,35 @@ class CloudMetaMgrTest : public testing::Test {
     void TearDown() override {}
 };
 
+static AbortTxnRequest get_abort_txn_request(CloudMetaMgr* meta_mgr, const 
StreamLoadContext& ctx) {
+    auto* sp = SyncPoint::get_instance();
+    sp->clear_all_call_backs();
+    sp->enable_processing();
+
+    bool called = false;
+    AbortTxnRequest captured_req;
+    SyncPoint::CallbackGuard guard;
+    sp->set_call_back(
+            "CloudMetaMgr::abort_txn.before_rpc",
+            [&](auto&& args) {
+                auto* req = try_any_cast<AbortTxnRequest*>(args[0]);
+                captured_req.CopyFrom(*req);
+                called = true;
+                auto* ret = try_any_cast<std::pair<Status, 
bool>*>(args.back());
+                ret->first = Status::OK();
+                ret->second = true;
+            },
+            &guard);
+
+    Status status = meta_mgr->abort_txn(ctx);
+
+    EXPECT_TRUE(status.ok()) << "Status: " << status;
+    EXPECT_TRUE(called);
+    sp->disable_processing();
+    sp->clear_all_call_backs();
+    return captured_req;
+}
+
 TEST_F(CloudMetaMgrTest, bthread_fork_join_test) {
     // clang-format off
     std::atomic<int> task_counter{0};
@@ -170,6 +200,38 @@ TEST_F(CloudMetaMgrTest, bthread_fork_join_test) {
     // clang-format on
 }
 
+TEST_F(CloudMetaMgrTest, abort_txn_prefers_txn_id_when_label_is_also_present) {
+    CloudMetaMgr meta_mgr;
+    StreamLoadContext ctx(nullptr);
+    ctx.db_id = 10001;
+    ctx.txn_id = 20002;
+    ctx.label = "same_label";
+    ctx.status = Status::InternalError<false>("load failed");
+
+    AbortTxnRequest captured_req = get_abort_txn_request(&meta_mgr, ctx);
+
+    EXPECT_TRUE(captured_req.has_txn_id());
+    EXPECT_EQ(captured_req.txn_id(), ctx.txn_id);
+    EXPECT_FALSE(captured_req.has_db_id());
+    EXPECT_FALSE(captured_req.has_label());
+}
+
+TEST_F(CloudMetaMgrTest, abort_txn_uses_label_when_txn_id_is_missing) {
+    CloudMetaMgr meta_mgr;
+    StreamLoadContext ctx(nullptr);
+    ctx.db_id = 10001;
+    ctx.label = "same_label";
+    ctx.status = Status::InternalError<false>("load failed");
+
+    AbortTxnRequest captured_req = get_abort_txn_request(&meta_mgr, ctx);
+
+    EXPECT_FALSE(captured_req.has_txn_id());
+    EXPECT_TRUE(captured_req.has_db_id());
+    EXPECT_EQ(captured_req.db_id(), ctx.db_id);
+    EXPECT_TRUE(captured_req.has_label());
+    EXPECT_EQ(captured_req.label(), ctx.label);
+}
+
 TEST_F(CloudMetaMgrTest, test_fill_version_holes_no_holes) {
     CloudStorageEngine engine(EngineOptions {});
     CloudMetaMgr meta_mgr;


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to