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

lizhimins pushed a commit to branch rocketmq-studio
in repository https://gitbox.apache.org/repos/asf/rocketmq-dashboard.git


The following commit(s) were added to refs/heads/rocketmq-studio by this push:
     new cf545e5a9 fix(instance): do not recreate instances deleted during 
update (#2524)
cf545e5a9 is described below

commit cf545e5a985236ac7d410dfe0938c5e582b3063d
Author: 0 <[email protected]>
AuthorDate: Sat Aug 22 15:29:32 2026 +0800

    fix(instance): do not recreate instances deleted during update (#2524)
    
    save() re-queried the row and fell back to an insert whenever the lookup 
came up empty. An instance that another request deleted between the service 
read and this write was therefore resurrected under its old id, with a spurious 
success audit.
    
    A non-null id now always takes the update path: a zero-row update (the row 
vanished) is reported as a 409 instead of an insert, so a deleted instance 
stays deleted. A null id still inserts.
    
    Fixes #2494
---
 .../studio/instance/MybatisPlusInstanceRepository.java      |  6 +++++-
 .../studio/instance/MybatisPlusInstanceRepositoryTest.java  | 13 ++++++-------
 2 files changed, 11 insertions(+), 8 deletions(-)

diff --git 
a/server/src/main/java/org/apache/rocketmq/studio/instance/MybatisPlusInstanceRepository.java
 
b/server/src/main/java/org/apache/rocketmq/studio/instance/MybatisPlusInstanceRepository.java
index 1452fbbf1..63b3e4d05 100644
--- 
a/server/src/main/java/org/apache/rocketmq/studio/instance/MybatisPlusInstanceRepository.java
+++ 
b/server/src/main/java/org/apache/rocketmq/studio/instance/MybatisPlusInstanceRepository.java
@@ -114,7 +114,11 @@ public class MybatisPlusInstanceRepository implements 
InstanceRepository {
     @Transactional
     public InstanceVO save(InstanceVO instance) {
         RmqInstance entity = toEntity(instance);
-        if (entity.getId() != null && 
instanceMapper.selectById(entity.getId()) != null) {
+        if (entity.getId() != null) {
+            // A non-null id identifies an existing instance, so the update 
path must only
+            // update. If the row vanished (concurrent delete), a zero-row 
update is a
+            // conflict; re-inserting here would resurrect the deleted 
instance under its
+            // old id.
             if (instanceMapper.updateById(entity) == 0) {
                 throw new BusinessException(409,
                         "Instance update was not applied: " + entity.getId());
diff --git 
a/server/src/test/java/org/apache/rocketmq/studio/instance/MybatisPlusInstanceRepositoryTest.java
 
b/server/src/test/java/org/apache/rocketmq/studio/instance/MybatisPlusInstanceRepositoryTest.java
index 3aa83c2fa..40cbe0f14 100644
--- 
a/server/src/test/java/org/apache/rocketmq/studio/instance/MybatisPlusInstanceRepositoryTest.java
+++ 
b/server/src/test/java/org/apache/rocketmq/studio/instance/MybatisPlusInstanceRepositoryTest.java
@@ -185,9 +185,8 @@ class MybatisPlusInstanceRepositoryTest {
     }
 
     @Test
-    void saveShouldInsertWhenInstanceAbsent() {
-        InstanceVO vo = vo(5L, "instance-proxy-2", InstanceType.PROXY_CLUSTER);
-        when(instanceMapper.selectById(5L)).thenReturn(null);
+    void saveShouldInsertWhenInstanceIdIsAbsent() {
+        InstanceVO vo = vo(null, "instance-proxy-2", 
InstanceType.PROXY_CLUSTER);
 
         repository.save(vo);
 
@@ -200,7 +199,6 @@ class MybatisPlusInstanceRepositoryTest {
     @Test
     void saveShouldUpdateWhenInstanceExists() {
         InstanceVO vo = vo(5L, "instance-proxy-2", InstanceType.PROXY_CLUSTER);
-        when(instanceMapper.selectById(5L)).thenReturn(entity(5L, 
"instance-proxy-2", InstanceType.PROXY_CLUSTER));
         when(instanceMapper.updateById(any(RmqInstance.class))).thenReturn(1);
 
         repository.save(vo);
@@ -210,16 +208,17 @@ class MybatisPlusInstanceRepositoryTest {
     }
 
     @Test
-    void saveShouldReportALostConcurrentUpdate() {
+    void saveShouldNotResurrectAnInstanceDeletedDuringUpdate() {
+        // The service read the instance (id 5) and another request deleted it 
before this
+        // write: the update touches zero rows and must fail instead of 
re-inserting id 5.
         InstanceVO vo = vo(5L, "instance-proxy-2", InstanceType.PROXY_CLUSTER);
-        when(instanceMapper.selectById(5L))
-                .thenReturn(entity(5L, "instance-proxy-2", 
InstanceType.PROXY_CLUSTER));
         when(instanceMapper.updateById(any(RmqInstance.class))).thenReturn(0);
 
         assertThatThrownBy(() -> repository.save(vo))
                 .isInstanceOf(BusinessException.class)
                 .hasMessage("Instance update was not applied: 5")
                 .satisfies(error -> assertThat(((BusinessException) 
error).getCode()).isEqualTo(409));
+        verify(instanceMapper, never()).insert(any(RmqInstance.class));
     }
 
     @Test

Reply via email to