tju-yxq opened a new issue, #6174:
URL: https://github.com/apache/rocketmq-dashboard/issues/6174

   ### Describe the bug
   
   `ResourceOwnershipGuardTest.migrationConcurrentStartupIsIdempotentTest` 
fails intermittently — and in practice very often — with an 
`ExecutionException` wrapping an H2 `General error: 
"java.util.ConcurrentModificationException"`. On this machine the single test 
method fails **7 out of 10 consecutive runs**; on GitHub's CI runners today 
alone, a dozen unrelated PR runs had their `Backend Tests (Java 21)` check go 
red on this one test (it fails on pure-frontend PRs too, which is the clearest 
sign it is the test environment racing, not the change under review).
   
   ### To reproduce
   
   ```
   cd server
   for i in 1..10: mvn test 
-Dtest='ResourceOwnershipGuardTest#migrationConcurrentStartupIsIdempotentTest'
   # observed: 7 of 10 runs fail
   ```
   
   ```
   java.util.concurrent.ExecutionException: 
org.h2.jdbc.JdbcSQLNonTransientException:
       General error: "java.util.ConcurrentModificationException" [50000-240]
       at 
ResourceOwnershipSchemaMigration.afterPropertiesSet(ResourceOwnershipSchemaMigration.java:50)
   Caused by: java.util.ConcurrentModificationException
       at java.util.ArrayList$Itr.checkForComodification
       at org.h2.command.query.Select.getGroupSortedIndex(Select.java:365)
       at org.h2.command.query.Select.preparePlan(Select.java:1297)
       ...
   ```
   
   ### Root cause
   
   The test simulates two studio nodes starting at the same time by running 
`ResourceOwnershipSchemaMigration.afterPropertiesSet()` on two threads against 
one shared in-memory H2 database:
   
   - thread A prepares the validation `SELECT name, COUNT(*) FROM 
rmq_instance_topic GROUP BY name ...`; H2's planner picks a group-sorted index 
and **iterates the table's index list** (`Select.getGroupSortedIndex`);
   - thread B commits its `CREATE TABLE`/`CREATE INDEX` DDL, which **mutates 
that same list**;
   - H2 has no metadata locking, so the planner's iteration hits a 
`ConcurrentModificationException`, which H2 rethrows as `General error`.
   
   In production, two real nodes are serialized by MySQL's metadata locks (a 
query plan blocks on the other node's DDL), so the migration logic itself is 
not wrong across nodes — including the `CREATE ... IF NOT EXISTS` and the 
catch-and-recheck in `ensureIndex`, which already tolerate a *completed* 
concurrent DDL. The gap is that **nothing serializes two overlapping executions 
inside a single process**: the regression test itself, or two Spring contexts 
sharing one test database.
   
   ### Expected behavior
   
   Overlapping in-process executions of the migration wait for each other (the 
way Flyway serializes its migrations in-process) instead of racing the engine, 
and the concurrent-startup regression test passes deterministically.
   
   ### Additional context
   
   Same symptom previously reported in #5302 and re-filed as #6022 — this 
report adds the 70% reproduction rate, the exact failing statement, and the H2 
planner stack. Suggested fix: a process-wide mutex around the migration body, 
submitted as a PR referencing this issue.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to