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