From 64fc0391031ac233d86053f1909bd2e1f4b84d0b Mon Sep 17 00:00:00 2001 From: legendPei <804141866@qq.com> Date: Wed, 3 Jun 2026 17:03:58 +0800 Subject: [PATCH 01/19] feat(config): add rocksdb file engine option --- .../seata/common/ConfigurationKeys.java | 15 ++++++ .../apache/seata/common/store/LockMode.java | 6 ++- .../seata/server/store/FileStoreEngine.java | 50 +++++++++++++++++++ .../seata/server/store/StoreConfig.java | 47 +++++++++++++++-- .../main/resources/application.example.yml | 5 ++ server/src/main/resources/application.yml | 3 ++ .../boot/autoconfigure/StarterConstants.java | 1 + .../loader/SeataPropertiesLoader.java | 2 +- .../SeataServerEnvironmentPostProcessor.java | 2 + .../server/store/StoreFileProperties.java | 26 ++++++++++ 10 files changed, 151 insertions(+), 6 deletions(-) create mode 100644 server/src/main/java/org/apache/seata/server/store/FileStoreEngine.java diff --git a/common/src/main/java/org/apache/seata/common/ConfigurationKeys.java b/common/src/main/java/org/apache/seata/common/ConfigurationKeys.java index e31bc8e72e2..a35cac0c246 100644 --- a/common/src/main/java/org/apache/seata/common/ConfigurationKeys.java +++ b/common/src/main/java/org/apache/seata/common/ConfigurationKeys.java @@ -138,6 +138,21 @@ public interface ConfigurationKeys { */ String STORE_FILE_DIR = STORE_FILE_PREFIX + "dir"; + /** + * The constant STORE_FILE_ENGINE + */ + String STORE_FILE_ENGINE = STORE_FILE_PREFIX + "engine"; + + /** + * The constant STORE_FILE_ROCKSDB_PREFIX + */ + String STORE_FILE_ROCKSDB_PREFIX = STORE_FILE_PREFIX + "rocksdb."; + + /** + * The constant STORE_FILE_ROCKSDB_DIR + */ + String STORE_FILE_ROCKSDB_DIR = STORE_FILE_ROCKSDB_PREFIX + "dir"; + /** * The constant SERVICE_GROUP_MAPPING_PREFIX. */ diff --git a/common/src/main/java/org/apache/seata/common/store/LockMode.java b/common/src/main/java/org/apache/seata/common/store/LockMode.java index 23abb91ba0a..4a5e5c5e27e 100644 --- a/common/src/main/java/org/apache/seata/common/store/LockMode.java +++ b/common/src/main/java/org/apache/seata/common/store/LockMode.java @@ -32,7 +32,11 @@ public enum LockMode { /** * raft store */ - RAFT("raft"); + RAFT("raft"), + /** + * RocksDB lock mode for file store engine. + */ + ROCKSDB("rocksdb"); private String name; diff --git a/server/src/main/java/org/apache/seata/server/store/FileStoreEngine.java b/server/src/main/java/org/apache/seata/server/store/FileStoreEngine.java new file mode 100644 index 00000000000..b978c8fad2f --- /dev/null +++ b/server/src/main/java/org/apache/seata/server/store/FileStoreEngine.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.seata.server.store; + +/** + * The file store engine inside file mode. + */ +public enum FileStoreEngine { + /** + * The default file log engine. + */ + FILE("file"), + /** + * The RocksDB engine. + */ + ROCKSDB("rocksdb"); + + private final String name; + + FileStoreEngine(String name) { + this.name = name; + } + + public static FileStoreEngine get(String name) { + for (FileStoreEngine engine : FileStoreEngine.values()) { + if (engine.getName().equalsIgnoreCase(name)) { + return engine; + } + } + throw new IllegalArgumentException("unknown file store engine:" + name); + } + + public String getName() { + return name; + } +} diff --git a/server/src/main/java/org/apache/seata/server/store/StoreConfig.java b/server/src/main/java/org/apache/seata/server/store/StoreConfig.java index 89f1e3f3fea..2068bb944f2 100644 --- a/server/src/main/java/org/apache/seata/server/store/StoreConfig.java +++ b/server/src/main/java/org/apache/seata/server/store/StoreConfig.java @@ -16,18 +16,19 @@ */ package org.apache.seata.server.store; +import org.apache.seata.common.ConfigurationKeys; +import org.apache.seata.common.exception.StoreException; import org.apache.seata.common.store.LockMode; import org.apache.seata.common.store.SessionMode; import org.apache.seata.common.store.StoreMode; import org.apache.seata.common.util.StringUtils; import org.apache.seata.config.Configuration; import org.apache.seata.config.ConfigurationFactory; -import org.apache.seata.core.constants.ConfigurationKeys; import org.apache.seata.server.env.ContainerHelper; import org.apache.seata.server.storage.file.FlushDiskMode; +import static org.apache.seata.common.ConfigurationKeys.STORE_FILE_PREFIX; import static org.apache.seata.common.DefaultValues.SERVER_DEFAULT_STORE_MODE; -import static org.apache.seata.core.constants.ConfigurationKeys.STORE_FILE_PREFIX; /** */ @@ -88,6 +89,17 @@ public static FlushDiskMode getFlushDiskMode() { return FlushDiskMode.findDiskMode(CONFIGURATION.getConfig(STORE_FILE_PREFIX + "flushDiskMode")); } + public static FileStoreEngine getFileEngine() { + String fileEngine = + CONFIGURATION.getConfig(ConfigurationKeys.STORE_FILE_ENGINE, FileStoreEngine.FILE.getName()); + try { + return FileStoreEngine.get(fileEngine); + } catch (IllegalArgumentException e) { + throw new StoreException( + "unknown file store engine:" + fileEngine + ", config:" + ConfigurationKeys.STORE_FILE_ENGINE); + } + } + /** * only for inner call * @@ -128,6 +140,34 @@ public static SessionMode getSessionMode() { } public static LockMode getLockMode() { + LockMode configuredLockMode = getConfiguredLockMode(); + if (configuredLockMode != null) { + return configuredLockMode; + } + // complication old config + return LockMode.get(getStoreMode().name()); + } + + public static LockMode getEffectiveLockMode() { + LockMode configuredLockMode = getConfiguredLockMode(); + if (StoreMode.FILE == getStoreMode() && FileStoreEngine.ROCKSDB == getFileEngine()) { + if (configuredLockMode != null && configuredLockMode != LockMode.ROCKSDB) { + throw new StoreException("RocksDB file engine requires rocksdb lock mode, but configured lock mode is " + + configuredLockMode.getName()); + } + return LockMode.ROCKSDB; + } + if (configuredLockMode == LockMode.ROCKSDB) { + throw new StoreException("RocksDB lock mode requires store.mode=file and store.file.engine=rocksdb"); + } + if (configuredLockMode != null) { + return configuredLockMode; + } + // complication old config + return LockMode.get(getStoreMode().name()); + } + + private static LockMode getConfiguredLockMode() { // startup if (null != lockMode) { return lockMode; @@ -142,7 +182,6 @@ public static LockMode getLockMode() { if (StringUtils.isNotBlank(lockModeConfig)) { return LockMode.get(lockModeConfig); } - // complication old config - return LockMode.get(getStoreMode().name()); + return null; } } diff --git a/server/src/main/resources/application.example.yml b/server/src/main/resources/application.example.yml index eff0d0bbbe8..cf7a0201b13 100644 --- a/server/src/main/resources/application.example.yml +++ b/server/src/main/resources/application.example.yml @@ -189,12 +189,17 @@ seata: lock: mode: file file: + # support: file, rocksdb + engine: file dir: sessionStore max-branch-session-size: 16384 max-global-session-size: 512 file-write-buffer-cache-size: 16384 session-reload-read-size: 100 flush-disk-mode: async + rocksdb: + # Phase1 only reserves the config key; RocksDB engine becomes available in Phase2. + dir: sessionStore/rocksdb db: datasource: druid db-type: mysql diff --git a/server/src/main/resources/application.yml b/server/src/main/resources/application.yml index e7d7c3c2bc4..5f1a2741844 100644 --- a/server/src/main/resources/application.yml +++ b/server/src/main/resources/application.yml @@ -53,5 +53,8 @@ seata: store: # support: file 、 db 、 redis 、 raft mode: file + file: + # support: file, rocksdb + engine: file # server: # service-port: 8091 #If not configured, the default is '${server.port} + 1000' diff --git a/spring/seata-spring-autoconfigure/seata-spring-autoconfigure-core/src/main/java/org/apache/seata/spring/boot/autoconfigure/StarterConstants.java b/spring/seata-spring-autoconfigure/seata-spring-autoconfigure-core/src/main/java/org/apache/seata/spring/boot/autoconfigure/StarterConstants.java index e63341fed04..95b29767f3f 100644 --- a/spring/seata-spring-autoconfigure/seata-spring-autoconfigure-core/src/main/java/org/apache/seata/spring/boot/autoconfigure/StarterConstants.java +++ b/spring/seata-spring-autoconfigure/seata-spring-autoconfigure-core/src/main/java/org/apache/seata/spring/boot/autoconfigure/StarterConstants.java @@ -101,6 +101,7 @@ public interface StarterConstants { String STORE_SESSION_PREFIX = STORE_PREFIX + ".session"; String STORE_LOCK_PREFIX = STORE_PREFIX + ".lock"; String STORE_FILE_PREFIX = STORE_PREFIX + ".file"; + String STORE_FILE_ROCKSDB_PREFIX = STORE_FILE_PREFIX + ".rocksdb"; String STORE_DB_PREFIX = STORE_PREFIX + ".db"; String STORE_DB_DRUID_PREFIX = STORE_DB_PREFIX + ".druid"; String STORE_DB_HIKARI_PREFIX = STORE_DB_PREFIX + ".hikari"; diff --git a/spring/seata-spring-autoconfigure/seata-spring-autoconfigure-core/src/main/java/org/apache/seata/spring/boot/autoconfigure/loader/SeataPropertiesLoader.java b/spring/seata-spring-autoconfigure/seata-spring-autoconfigure-core/src/main/java/org/apache/seata/spring/boot/autoconfigure/loader/SeataPropertiesLoader.java index 9b24c79e0c8..f747943f1c5 100644 --- a/spring/seata-spring-autoconfigure/seata-spring-autoconfigure-core/src/main/java/org/apache/seata/spring/boot/autoconfigure/loader/SeataPropertiesLoader.java +++ b/spring/seata-spring-autoconfigure/seata-spring-autoconfigure-core/src/main/java/org/apache/seata/spring/boot/autoconfigure/loader/SeataPropertiesLoader.java @@ -93,7 +93,7 @@ public void loadSessionAndLockModes() { try { Class storeConfigClass = Class.forName("org.apache.seata.server.store.StoreConfig"); Optional sessionMode = invokeEnumMethod(storeConfigClass, "getSessionMode", "getName"); - Optional lockMode = invokeEnumMethod(storeConfigClass, "getLockMode", "getName"); + Optional lockMode = invokeEnumMethod(storeConfigClass, "getEffectiveLockMode", "getName"); sessionMode.ifPresent(value -> System.setProperty("sessionMode", value)); lockMode.ifPresent(value -> System.setProperty("lockMode", value)); } catch (ClassNotFoundException diff --git a/spring/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/main/java/org/apache/seata/spring/boot/autoconfigure/SeataServerEnvironmentPostProcessor.java b/spring/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/main/java/org/apache/seata/spring/boot/autoconfigure/SeataServerEnvironmentPostProcessor.java index d0365d09b8c..86086296319 100644 --- a/spring/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/main/java/org/apache/seata/spring/boot/autoconfigure/SeataServerEnvironmentPostProcessor.java +++ b/spring/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/main/java/org/apache/seata/spring/boot/autoconfigure/SeataServerEnvironmentPostProcessor.java @@ -60,6 +60,7 @@ import static org.apache.seata.spring.boot.autoconfigure.StarterConstants.STORE_DB_HIKARI_PREFIX; import static org.apache.seata.spring.boot.autoconfigure.StarterConstants.STORE_DB_PREFIX; import static org.apache.seata.spring.boot.autoconfigure.StarterConstants.STORE_FILE_PREFIX; +import static org.apache.seata.spring.boot.autoconfigure.StarterConstants.STORE_FILE_ROCKSDB_PREFIX; import static org.apache.seata.spring.boot.autoconfigure.StarterConstants.STORE_LOCK_PREFIX; import static org.apache.seata.spring.boot.autoconfigure.StarterConstants.STORE_PREFIX; import static org.apache.seata.spring.boot.autoconfigure.StarterConstants.STORE_REDIS_PREFIX; @@ -90,6 +91,7 @@ public static void init() { PROPERTY_BEAN_MAP.put(STORE_SESSION_PREFIX, Session.class); PROPERTY_BEAN_MAP.put(STORE_LOCK_PREFIX, Lock.class); PROPERTY_BEAN_MAP.put(STORE_FILE_PREFIX, StoreFileProperties.class); + PROPERTY_BEAN_MAP.put(STORE_FILE_ROCKSDB_PREFIX, StoreFileProperties.RocksDB.class); PROPERTY_BEAN_MAP.put(STORE_DB_PREFIX, StoreDBProperties.class); PROPERTY_BEAN_MAP.put(STORE_DB_DRUID_PREFIX, DruidProperties.class); PROPERTY_BEAN_MAP.put(STORE_DB_HIKARI_PREFIX, HikariProperties.class); diff --git a/spring/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/main/java/org/apache/seata/spring/boot/autoconfigure/properties/server/store/StoreFileProperties.java b/spring/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/main/java/org/apache/seata/spring/boot/autoconfigure/properties/server/store/StoreFileProperties.java index 3a33624312a..c3a386c8a31 100644 --- a/spring/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/main/java/org/apache/seata/spring/boot/autoconfigure/properties/server/store/StoreFileProperties.java +++ b/spring/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/main/java/org/apache/seata/spring/boot/autoconfigure/properties/server/store/StoreFileProperties.java @@ -21,10 +21,12 @@ import static org.apache.seata.common.DefaultValues.DEFAULT_SERVICE_SESSION_RELOAD_READ_SIZE; import static org.apache.seata.spring.boot.autoconfigure.StarterConstants.STORE_FILE_PREFIX; +import static org.apache.seata.spring.boot.autoconfigure.StarterConstants.STORE_FILE_ROCKSDB_PREFIX; @Component @ConfigurationProperties(prefix = STORE_FILE_PREFIX) public class StoreFileProperties { + private String engine = "file"; private String dir = "sessionStore"; private Integer maxBranchSessionSize = 16384; private Integer maxGlobalSessionSize = 512; @@ -32,6 +34,15 @@ public class StoreFileProperties { private Integer sessionReloadReadSize = DEFAULT_SERVICE_SESSION_RELOAD_READ_SIZE; private String flushDiskMode = "async"; + public String getEngine() { + return engine; + } + + public StoreFileProperties setEngine(String engine) { + this.engine = engine; + return this; + } + public String getDir() { return dir; } @@ -85,4 +96,19 @@ public StoreFileProperties setFlushDiskMode(String flushDiskMode) { this.flushDiskMode = flushDiskMode; return this; } + + @Component + @ConfigurationProperties(prefix = STORE_FILE_ROCKSDB_PREFIX) + public static class RocksDB { + private String dir = "sessionStore/rocksdb"; + + public String getDir() { + return dir; + } + + public RocksDB setDir(String dir) { + this.dir = dir; + return this; + } + } } From 085bbba0a5e410ecfac4316986ede6ae6558e6c0 Mon Sep 17 00:00:00 2001 From: legendPei <804141866@qq.com> Date: Wed, 3 Jun 2026 17:04:39 +0800 Subject: [PATCH 02/19] feat(lock): add rocksdb lock mode routing --- .../server/lock/LockerManagerFactory.java | 11 +-- .../rocksdb/lock/RocksDBLockManager.java | 80 +++++++++++++++++++ .../org.apache.seata.server.lock.LockManager | 3 +- 3 files changed, 84 insertions(+), 10 deletions(-) create mode 100644 server/src/main/java/org/apache/seata/server/storage/rocksdb/lock/RocksDBLockManager.java diff --git a/server/src/main/java/org/apache/seata/server/lock/LockerManagerFactory.java b/server/src/main/java/org/apache/seata/server/lock/LockerManagerFactory.java index a301fa563a1..b1f11bef3ed 100644 --- a/server/src/main/java/org/apache/seata/server/lock/LockerManagerFactory.java +++ b/server/src/main/java/org/apache/seata/server/lock/LockerManagerFactory.java @@ -18,9 +18,6 @@ import org.apache.seata.common.loader.EnhancedServiceLoader; import org.apache.seata.common.store.LockMode; -import org.apache.seata.common.store.StoreMode; -import org.apache.seata.config.Configuration; -import org.apache.seata.config.ConfigurationFactory; import org.apache.seata.server.store.StoreConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,7 +29,6 @@ public class LockerManagerFactory { private static final Logger LOGGER = LoggerFactory.getLogger(LockerManagerFactory.class); - private static final Configuration CONFIG = ConfigurationFactory.getInstance(); /** * the lock manager @@ -62,13 +58,10 @@ public static void init(LockMode lockMode) { synchronized (LockerManagerFactory.class) { if (LOCK_MANAGER == null) { if (null == lockMode) { - lockMode = StoreConfig.getLockMode(); + lockMode = StoreConfig.getEffectiveLockMode(); } LOGGER.info("use lock store mode: {}", lockMode.getName()); - // if not exist the lock mode, throw exception - if (null != StoreMode.get(lockMode.name())) { - LOCK_MANAGER = EnhancedServiceLoader.load(LockManager.class, lockMode.getName()); - } + LOCK_MANAGER = EnhancedServiceLoader.load(LockManager.class, lockMode.getName()); } } } diff --git a/server/src/main/java/org/apache/seata/server/storage/rocksdb/lock/RocksDBLockManager.java b/server/src/main/java/org/apache/seata/server/storage/rocksdb/lock/RocksDBLockManager.java new file mode 100644 index 00000000000..50dc8194fcc --- /dev/null +++ b/server/src/main/java/org/apache/seata/server/storage/rocksdb/lock/RocksDBLockManager.java @@ -0,0 +1,80 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.seata.server.storage.rocksdb.lock; + +import org.apache.seata.common.exception.StoreException; +import org.apache.seata.common.loader.LoadLevel; +import org.apache.seata.core.exception.TransactionException; +import org.apache.seata.core.lock.Locker; +import org.apache.seata.core.model.LockStatus; +import org.apache.seata.server.lock.AbstractLockManager; +import org.apache.seata.server.session.BranchSession; +import org.apache.seata.server.session.GlobalSession; + +/** + * The RocksDB lock manager placeholder for file store engine. + */ +@LoadLevel(name = "rocksdb") +public class RocksDBLockManager extends AbstractLockManager { + + private static final String NOT_IMPLEMENTED = "RocksDB lock manager is not implemented in Phase1"; + + @Override + public boolean acquireLock(BranchSession branchSession) throws TransactionException { + throw notImplemented(); + } + + @Override + public boolean acquireLock(BranchSession branchSession, boolean autoCommit, boolean skipCheckLock) + throws TransactionException { + throw notImplemented(); + } + + @Override + public boolean releaseLock(BranchSession branchSession) throws TransactionException { + throw notImplemented(); + } + + @Override + public boolean releaseGlobalSessionLock(GlobalSession globalSession) throws TransactionException { + throw notImplemented(); + } + + @Override + public boolean isLockable(String xid, String resourceId, String lockKey) throws TransactionException { + throw notImplemented(); + } + + @Override + public void cleanAllLocks() throws TransactionException { + throw notImplemented(); + } + + @Override + public void updateLockStatus(String xid, LockStatus lockStatus) { + throw notImplemented(); + } + + @Override + protected Locker getLocker(BranchSession branchSession) { + throw notImplemented(); + } + + private StoreException notImplemented() { + return new StoreException(NOT_IMPLEMENTED); + } +} diff --git a/server/src/main/resources/META-INF/services/org.apache.seata.server.lock.LockManager b/server/src/main/resources/META-INF/services/org.apache.seata.server.lock.LockManager index c6f6f41e14a..a4ee2594e8b 100644 --- a/server/src/main/resources/META-INF/services/org.apache.seata.server.lock.LockManager +++ b/server/src/main/resources/META-INF/services/org.apache.seata.server.lock.LockManager @@ -17,4 +17,5 @@ org.apache.seata.server.storage.db.lock.DataBaseLockManager org.apache.seata.server.storage.file.lock.FileLockManager org.apache.seata.server.storage.redis.lock.RedisLockManager -org.apache.seata.server.storage.raft.lock.RaftLockManager \ No newline at end of file +org.apache.seata.server.storage.raft.lock.RaftLockManager +org.apache.seata.server.storage.rocksdb.lock.RocksDBLockManager From f0e93b869c240415600fc289fbad215718842bc9 Mon Sep 17 00:00:00 2001 From: legendPei <804141866@qq.com> Date: Wed, 3 Jun 2026 17:04:53 +0800 Subject: [PATCH 03/19] feat(session): fail fast for rocksdb file engine --- .../java/org/apache/seata/server/session/SessionHolder.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server/src/main/java/org/apache/seata/server/session/SessionHolder.java b/server/src/main/java/org/apache/seata/server/session/SessionHolder.java index 32baf181503..ac6eccab276 100644 --- a/server/src/main/java/org/apache/seata/server/session/SessionHolder.java +++ b/server/src/main/java/org/apache/seata/server/session/SessionHolder.java @@ -34,6 +34,7 @@ import org.apache.seata.server.cluster.raft.RaftServerManager; import org.apache.seata.server.cluster.raft.context.SeataClusterContext; import org.apache.seata.server.lock.distributed.DistributedLockerFactory; +import org.apache.seata.server.store.FileStoreEngine; import org.apache.seata.server.store.StoreConfig; import org.apache.seata.server.store.VGroupMappingStoreManager; import org.slf4j.Logger; @@ -121,6 +122,10 @@ public static void init(SessionMode sessionMode) { RaftServerManager.init(); RaftServerManager.start(); } else { + FileStoreEngine fileStoreEngine = StoreConfig.getFileEngine(); + if (FileStoreEngine.ROCKSDB == fileStoreEngine) { + throw new StoreException("RocksDB file engine is not implemented in Phase1"); + } String vGroupMappingStorePath = CONFIG.getConfig(ConfigurationKeys.STORE_FILE_DIR, DEFAULT_VGROUP_MAPPING_STORE_FILE_DIR) + separator From 6acd51f89a4220965132322f6518840750e80695 Mon Sep 17 00:00:00 2001 From: legendPei <804141866@qq.com> Date: Wed, 3 Jun 2026 17:05:18 +0800 Subject: [PATCH 04/19] test(rocksdb): cover config and spi routing --- .../seata/common/store/LockModeTest.java | 4 + .../server/lock/LockerManagerFactoryTest.java | 68 +++++++++++ .../server/session/SessionHolderTest.java | 16 +++ .../loader/SeataPropertiesLoaderTest.java | 81 +++++++++++++ .../server/store/FileStoreEngineTest.java | 44 +++++++ .../seata/server/store/StoreConfigTest.java | 110 ++++++++++++++++++ .../org.apache.seata.server.lock.LockManager | 3 +- .../autoconfigure/ServerPropertiesTest.java | 3 + .../server/store/StoreFilePropertiesTest.java | 5 + 9 files changed, 333 insertions(+), 1 deletion(-) create mode 100644 server/src/test/java/org/apache/seata/server/lock/LockerManagerFactoryTest.java create mode 100644 server/src/test/java/org/apache/seata/server/spring/loader/SeataPropertiesLoaderTest.java create mode 100644 server/src/test/java/org/apache/seata/server/store/FileStoreEngineTest.java create mode 100644 server/src/test/java/org/apache/seata/server/store/StoreConfigTest.java diff --git a/common/src/test/java/org/apache/seata/common/store/LockModeTest.java b/common/src/test/java/org/apache/seata/common/store/LockModeTest.java index cff12f3f485..fbae5dd3c4b 100644 --- a/common/src/test/java/org/apache/seata/common/store/LockModeTest.java +++ b/common/src/test/java/org/apache/seata/common/store/LockModeTest.java @@ -27,6 +27,7 @@ void testGetName() { Assertions.assertEquals("db", LockMode.DB.getName()); Assertions.assertEquals("redis", LockMode.REDIS.getName()); Assertions.assertEquals("raft", LockMode.RAFT.getName()); + Assertions.assertEquals("rocksdb", LockMode.ROCKSDB.getName()); } @Test @@ -40,6 +41,8 @@ void testGet() { Assertions.assertEquals(LockMode.REDIS, LockMode.get("REDIS")); Assertions.assertEquals(LockMode.RAFT, LockMode.get("raft")); Assertions.assertEquals(LockMode.RAFT, LockMode.get("Raft")); + Assertions.assertEquals(LockMode.ROCKSDB, LockMode.get("rocksdb")); + Assertions.assertEquals(LockMode.ROCKSDB, LockMode.get("RocksDB")); } @Test @@ -57,6 +60,7 @@ void testContainsValid() { Assertions.assertTrue(LockMode.contains("db")); Assertions.assertTrue(LockMode.contains("redis")); Assertions.assertTrue(LockMode.contains("raft")); + Assertions.assertTrue(LockMode.contains("rocksdb")); } @Test diff --git a/server/src/test/java/org/apache/seata/server/lock/LockerManagerFactoryTest.java b/server/src/test/java/org/apache/seata/server/lock/LockerManagerFactoryTest.java new file mode 100644 index 00000000000..e1375d8304f --- /dev/null +++ b/server/src/test/java/org/apache/seata/server/lock/LockerManagerFactoryTest.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.seata.server.lock; + +import org.apache.seata.common.ConfigurationKeys; +import org.apache.seata.common.exception.StoreException; +import org.apache.seata.config.ConfigurationCache; +import org.apache.seata.server.BaseSpringBootTest; +import org.apache.seata.server.storage.file.lock.FileLockManager; +import org.apache.seata.server.storage.rocksdb.lock.RocksDBLockManager; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class LockerManagerFactoryTest extends BaseSpringBootTest { + + @BeforeEach + void beforeEach() { + clearConfig(); + } + + @AfterEach + void afterEach() { + clearConfig(); + } + + @Test + void testDefaultFileLockManager() { + LockerManagerFactory.init(); + Assertions.assertInstanceOf(FileLockManager.class, LockerManagerFactory.getLockManager()); + } + + @Test + void testRocksDBEffectiveLockManager() { + System.setProperty(ConfigurationKeys.STORE_FILE_ENGINE, "rocksdb"); + LockerManagerFactory.init(); + Assertions.assertInstanceOf(RocksDBLockManager.class, LockerManagerFactory.getLockManager()); + } + + @Test + void testRocksDBEffectiveLockManagerRejectsMixedLockMode() { + System.setProperty(ConfigurationKeys.STORE_FILE_ENGINE, "rocksdb"); + System.setProperty(ConfigurationKeys.STORE_LOCK_MODE, "file"); + Assertions.assertThrows(StoreException.class, LockerManagerFactory::init); + } + + private void clearConfig() { + LockerManagerFactory.destroy(); + System.clearProperty(ConfigurationKeys.STORE_LOCK_MODE); + System.clearProperty(ConfigurationKeys.STORE_FILE_ENGINE); + ConfigurationCache.clear(); + } +} diff --git a/server/src/test/java/org/apache/seata/server/session/SessionHolderTest.java b/server/src/test/java/org/apache/seata/server/session/SessionHolderTest.java index 692a37fc953..c175d8a4a81 100644 --- a/server/src/test/java/org/apache/seata/server/session/SessionHolderTest.java +++ b/server/src/test/java/org/apache/seata/server/session/SessionHolderTest.java @@ -17,6 +17,7 @@ package org.apache.seata.server.session; import org.apache.seata.common.XID; +import org.apache.seata.common.exception.StoreException; import org.apache.seata.common.store.SessionMode; import org.apache.seata.core.constants.ConfigurationKeys; import org.apache.seata.server.BaseSpringBootTest; @@ -76,8 +77,23 @@ public void testInit() throws IOException { } } + @Test + @Order(2) + public void testRocksDBFileEngineFailFastInPhase1() { + System.setProperty(ConfigurationKeys.STORE_FILE_ENGINE, "rocksdb"); + try { + StoreException exception = + Assertions.assertThrows(StoreException.class, () -> SessionHolder.init(SessionMode.FILE)); + Assertions.assertTrue(exception.getMessage().contains("RocksDB file engine is not implemented in Phase1")); + } finally { + System.clearProperty(ConfigurationKeys.STORE_FILE_ENGINE); + SessionHolder.destroy(); + } + } + @AfterEach public void after() { + System.clearProperty(ConfigurationKeys.STORE_FILE_ENGINE); final File actual = new File(pathname); if (actual.exists()) { actual.delete(); diff --git a/server/src/test/java/org/apache/seata/server/spring/loader/SeataPropertiesLoaderTest.java b/server/src/test/java/org/apache/seata/server/spring/loader/SeataPropertiesLoaderTest.java new file mode 100644 index 00000000000..c180bedb5ec --- /dev/null +++ b/server/src/test/java/org/apache/seata/server/spring/loader/SeataPropertiesLoaderTest.java @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.seata.server.spring.loader; + +import org.apache.seata.common.ConfigurationKeys; +import org.apache.seata.common.Constants; +import org.apache.seata.common.holder.ObjectHolder; +import org.apache.seata.config.ConfigurationCache; +import org.apache.seata.server.store.StoreConfig; +import org.apache.seata.spring.boot.autoconfigure.loader.SeataPropertiesLoader; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.mock.env.MockEnvironment; + +import java.lang.reflect.Field; + +class SeataPropertiesLoaderTest { + + @BeforeEach + void beforeEach() throws Exception { + clearConfig(); + } + + @AfterEach + void afterEach() throws Exception { + clearConfig(); + } + + @Test + void testLoadDefaultSessionAndLockModes() { + new SeataPropertiesLoader().loadSessionAndLockModes(); + + Assertions.assertEquals("file", System.getProperty("sessionMode")); + Assertions.assertEquals("file", System.getProperty("lockMode")); + } + + @Test + void testLoadEffectiveLockModeForRocksDBFileEngine() { + System.setProperty(ConfigurationKeys.STORE_FILE_ENGINE, "rocksdb"); + + new SeataPropertiesLoader().loadSessionAndLockModes(); + + Assertions.assertEquals("file", System.getProperty("sessionMode")); + Assertions.assertEquals("rocksdb", System.getProperty("lockMode")); + } + + private void clearConfig() throws Exception { + System.clearProperty("sessionMode"); + System.clearProperty("lockMode"); + System.clearProperty(ConfigurationKeys.STORE_MODE); + System.clearProperty(ConfigurationKeys.STORE_LOCK_MODE); + System.clearProperty(ConfigurationKeys.STORE_FILE_ENGINE); + ObjectHolder.INSTANCE.setObject(Constants.OBJECT_KEY_SPRING_CONFIGURABLE_ENVIRONMENT, new MockEnvironment()); + ConfigurationCache.clear(); + resetStoreConfig("storeMode"); + resetStoreConfig("sessionMode"); + resetStoreConfig("lockMode"); + } + + private void resetStoreConfig(String fieldName) throws Exception { + Field field = StoreConfig.class.getDeclaredField(fieldName); + field.setAccessible(true); + field.set(null, null); + } +} diff --git a/server/src/test/java/org/apache/seata/server/store/FileStoreEngineTest.java b/server/src/test/java/org/apache/seata/server/store/FileStoreEngineTest.java new file mode 100644 index 00000000000..842493a744b --- /dev/null +++ b/server/src/test/java/org/apache/seata/server/store/FileStoreEngineTest.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.seata.server.store; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +class FileStoreEngineTest { + + @Test + void testGetName() { + Assertions.assertEquals("file", FileStoreEngine.FILE.getName()); + Assertions.assertEquals("rocksdb", FileStoreEngine.ROCKSDB.getName()); + } + + @Test + void testGet() { + Assertions.assertEquals(FileStoreEngine.FILE, FileStoreEngine.get("file")); + Assertions.assertEquals(FileStoreEngine.FILE, FileStoreEngine.get("FILE")); + Assertions.assertEquals(FileStoreEngine.ROCKSDB, FileStoreEngine.get("rocksdb")); + Assertions.assertEquals(FileStoreEngine.ROCKSDB, FileStoreEngine.get("RocksDB")); + } + + @Test + void testGetUnknown() { + Assertions.assertThrows(IllegalArgumentException.class, () -> FileStoreEngine.get("unknown")); + Assertions.assertThrows(IllegalArgumentException.class, () -> FileStoreEngine.get("")); + Assertions.assertThrows(IllegalArgumentException.class, () -> FileStoreEngine.get(null)); + } +} diff --git a/server/src/test/java/org/apache/seata/server/store/StoreConfigTest.java b/server/src/test/java/org/apache/seata/server/store/StoreConfigTest.java new file mode 100644 index 00000000000..0dfd27afe18 --- /dev/null +++ b/server/src/test/java/org/apache/seata/server/store/StoreConfigTest.java @@ -0,0 +1,110 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.seata.server.store; + +import org.apache.seata.common.ConfigurationKeys; +import org.apache.seata.common.exception.StoreException; +import org.apache.seata.common.store.LockMode; +import org.apache.seata.config.ConfigurationCache; +import org.apache.seata.server.BaseSpringBootTest; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.lang.reflect.Field; + +class StoreConfigTest extends BaseSpringBootTest { + + @BeforeEach + void beforeEach() throws Exception { + clearConfig(); + } + + @AfterEach + void afterEach() throws Exception { + clearConfig(); + } + + @Test + void testDefaultFileEngine() { + Assertions.assertEquals(FileStoreEngine.FILE, StoreConfig.getFileEngine()); + } + + @Test + void testConfiguredFileEngine() { + System.setProperty(ConfigurationKeys.STORE_FILE_ENGINE, "rocksdb"); + Assertions.assertEquals(FileStoreEngine.ROCKSDB, StoreConfig.getFileEngine()); + + System.setProperty(ConfigurationKeys.STORE_FILE_ENGINE, "file"); + ConfigurationCache.clear(); + Assertions.assertEquals(FileStoreEngine.FILE, StoreConfig.getFileEngine()); + } + + @Test + void testInvalidFileEngine() { + System.setProperty(ConfigurationKeys.STORE_FILE_ENGINE, "unknown"); + Assertions.assertThrows(StoreException.class, StoreConfig::getFileEngine); + } + + @Test + void testDefaultEffectiveLockMode() { + Assertions.assertEquals(LockMode.FILE, StoreConfig.getEffectiveLockMode()); + } + + @Test + void testRocksDBEffectiveLockMode() { + System.setProperty(ConfigurationKeys.STORE_FILE_ENGINE, "rocksdb"); + Assertions.assertEquals(LockMode.ROCKSDB, StoreConfig.getEffectiveLockMode()); + } + + @Test + void testRocksDBEffectiveLockModeAllowsExplicitRocksDB() { + System.setProperty(ConfigurationKeys.STORE_FILE_ENGINE, "rocksdb"); + System.setProperty(ConfigurationKeys.STORE_LOCK_MODE, "rocksdb"); + Assertions.assertEquals(LockMode.ROCKSDB, StoreConfig.getEffectiveLockMode()); + } + + @Test + void testRocksDBEffectiveLockModeRejectsMixedLockMode() { + System.setProperty(ConfigurationKeys.STORE_FILE_ENGINE, "rocksdb"); + System.setProperty(ConfigurationKeys.STORE_LOCK_MODE, "file"); + Assertions.assertThrows(StoreException.class, StoreConfig::getEffectiveLockMode); + } + + @Test + void testRocksDBLockModeRequiresRocksDBFileEngine() { + System.setProperty(ConfigurationKeys.STORE_LOCK_MODE, "rocksdb"); + Assertions.assertThrows(StoreException.class, StoreConfig::getEffectiveLockMode); + } + + private void clearConfig() throws Exception { + System.clearProperty(ConfigurationKeys.STORE_MODE); + System.clearProperty(ConfigurationKeys.STORE_LOCK_MODE); + System.clearProperty(ConfigurationKeys.STORE_FILE_ENGINE); + ConfigurationCache.clear(); + resetStoreConfig("storeMode"); + resetStoreConfig("sessionMode"); + resetStoreConfig("lockMode"); + } + + private void resetStoreConfig(String fieldName) throws Exception { + Field field = StoreConfig.class.getDeclaredField(fieldName); + field.setAccessible(true); + field.set(null, null); + } +} diff --git a/server/src/test/resources/META-INF/services/org.apache.seata.server.lock.LockManager b/server/src/test/resources/META-INF/services/org.apache.seata.server.lock.LockManager index df4c40a0cab..f5d7ce2233c 100644 --- a/server/src/test/resources/META-INF/services/org.apache.seata.server.lock.LockManager +++ b/server/src/test/resources/META-INF/services/org.apache.seata.server.lock.LockManager @@ -16,4 +16,5 @@ # org.apache.seata.server.storage.db.lock.DataBaseLockManager org.apache.seata.server.storage.file.lock.FileLockManager -org.apache.seata.server.storage.redis.lock.RedisLockManager \ No newline at end of file +org.apache.seata.server.storage.redis.lock.RedisLockManager +org.apache.seata.server.storage.rocksdb.lock.RocksDBLockManager diff --git a/spring/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/test/java/org/apache/seata/spring/boot/autoconfigure/ServerPropertiesTest.java b/spring/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/test/java/org/apache/seata/spring/boot/autoconfigure/ServerPropertiesTest.java index c0dd4fb8170..c7f74610175 100644 --- a/spring/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/test/java/org/apache/seata/spring/boot/autoconfigure/ServerPropertiesTest.java +++ b/spring/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/test/java/org/apache/seata/spring/boot/autoconfigure/ServerPropertiesTest.java @@ -25,6 +25,7 @@ import org.apache.seata.spring.boot.autoconfigure.properties.server.store.HikariProperties; import org.apache.seata.spring.boot.autoconfigure.properties.server.store.StoreDBProperties; import org.apache.seata.spring.boot.autoconfigure.properties.server.store.StoreFileProperties; +import org.apache.seata.spring.boot.autoconfigure.properties.server.store.StoreFileProperties.RocksDB; import org.apache.seata.spring.boot.autoconfigure.properties.server.store.StoreProperties; import org.apache.seata.spring.boot.autoconfigure.properties.server.store.StoreRedisProperties; import org.apache.seata.spring.boot.autoconfigure.properties.server.store.StoreRedisProperties.Sentinel; @@ -77,6 +78,8 @@ public void testStoreProperties() { @Test public void testStoreFileProperties() { assertEquals(context.getBean(StoreFileProperties.class).getDir(), "sessionStore"); + assertEquals(context.getBean(StoreFileProperties.class).getEngine(), "file"); + assertEquals(context.getBean(RocksDB.class).getDir(), "sessionStore/rocksdb"); } @Test diff --git a/spring/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/test/java/org/apache/seata/spring/boot/autoconfigure/properties/server/store/StoreFilePropertiesTest.java b/spring/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/test/java/org/apache/seata/spring/boot/autoconfigure/properties/server/store/StoreFilePropertiesTest.java index 9f2c949b412..f1222382dc9 100644 --- a/spring/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/test/java/org/apache/seata/spring/boot/autoconfigure/properties/server/store/StoreFilePropertiesTest.java +++ b/spring/seata-spring-autoconfigure/seata-spring-autoconfigure-server/src/test/java/org/apache/seata/spring/boot/autoconfigure/properties/server/store/StoreFilePropertiesTest.java @@ -25,17 +25,22 @@ public class StoreFilePropertiesTest { public void testStoreFileProperties() { StoreFileProperties storeFileProperties = new StoreFileProperties(); storeFileProperties.setDir("dir"); + storeFileProperties.setEngine("rocksdb"); storeFileProperties.setFlushDiskMode("disk"); storeFileProperties.setFileWriteBufferCacheSize(1); storeFileProperties.setMaxBranchSessionSize(1); storeFileProperties.setMaxGlobalSessionSize(1); storeFileProperties.setSessionReloadReadSize(1); + StoreFileProperties.RocksDB rocksDB = new StoreFileProperties.RocksDB(); + rocksDB.setDir("rocksdb-dir"); Assertions.assertEquals("dir", storeFileProperties.getDir()); + Assertions.assertEquals("rocksdb", storeFileProperties.getEngine()); Assertions.assertEquals("disk", storeFileProperties.getFlushDiskMode()); Assertions.assertEquals(1, storeFileProperties.getFileWriteBufferCacheSize()); Assertions.assertEquals(1, storeFileProperties.getMaxGlobalSessionSize()); Assertions.assertEquals(1, storeFileProperties.getMaxBranchSessionSize()); Assertions.assertEquals(1, storeFileProperties.getSessionReloadReadSize()); + Assertions.assertEquals("rocksdb-dir", rocksDB.getDir()); } } From 7570d9bb59486ba50bf0a5593c178101c295fbb6 Mon Sep 17 00:00:00 2001 From: legendPei <804141866@qq.com> Date: Wed, 3 Jun 2026 21:40:04 +0800 Subject: [PATCH 05/19] fix(rocksdb): fail fast loader lock mode errors --- .../loader/SeataPropertiesLoaderTest.java | 26 +++++++++++++++++++ .../loader/SeataPropertiesLoader.java | 13 +++++++--- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/server/src/test/java/org/apache/seata/server/spring/loader/SeataPropertiesLoaderTest.java b/server/src/test/java/org/apache/seata/server/spring/loader/SeataPropertiesLoaderTest.java index c180bedb5ec..3219448f2e1 100644 --- a/server/src/test/java/org/apache/seata/server/spring/loader/SeataPropertiesLoaderTest.java +++ b/server/src/test/java/org/apache/seata/server/spring/loader/SeataPropertiesLoaderTest.java @@ -18,6 +18,7 @@ import org.apache.seata.common.ConfigurationKeys; import org.apache.seata.common.Constants; +import org.apache.seata.common.exception.StoreException; import org.apache.seata.common.holder.ObjectHolder; import org.apache.seata.config.ConfigurationCache; import org.apache.seata.server.store.StoreConfig; @@ -29,17 +30,22 @@ import org.springframework.mock.env.MockEnvironment; import java.lang.reflect.Field; +import java.util.Map; class SeataPropertiesLoaderTest { + private Object originalEnvironment; + @BeforeEach void beforeEach() throws Exception { + originalEnvironment = ObjectHolder.INSTANCE.getObject(Constants.OBJECT_KEY_SPRING_CONFIGURABLE_ENVIRONMENT); clearConfig(); } @AfterEach void afterEach() throws Exception { clearConfig(); + restoreEnvironment(); } @Test @@ -60,6 +66,14 @@ void testLoadEffectiveLockModeForRocksDBFileEngine() { Assertions.assertEquals("rocksdb", System.getProperty("lockMode")); } + @Test + void testLoadEffectiveLockModeRejectsMixedLockMode() { + System.setProperty(ConfigurationKeys.STORE_FILE_ENGINE, "rocksdb"); + System.setProperty(ConfigurationKeys.STORE_LOCK_MODE, "file"); + + Assertions.assertThrows(StoreException.class, () -> new SeataPropertiesLoader().loadSessionAndLockModes()); + } + private void clearConfig() throws Exception { System.clearProperty("sessionMode"); System.clearProperty("lockMode"); @@ -78,4 +92,16 @@ private void resetStoreConfig(String fieldName) throws Exception { field.setAccessible(true); field.set(null, null); } + + @SuppressWarnings("unchecked") + private void restoreEnvironment() throws Exception { + Field field = ObjectHolder.class.getDeclaredField("OBJECT_MAP"); + field.setAccessible(true); + Map objectMap = (Map) field.get(ObjectHolder.INSTANCE); + if (originalEnvironment == null) { + objectMap.remove(Constants.OBJECT_KEY_SPRING_CONFIGURABLE_ENVIRONMENT); + } else { + objectMap.put(Constants.OBJECT_KEY_SPRING_CONFIGURABLE_ENVIRONMENT, originalEnvironment); + } + } } diff --git a/spring/seata-spring-autoconfigure/seata-spring-autoconfigure-core/src/main/java/org/apache/seata/spring/boot/autoconfigure/loader/SeataPropertiesLoader.java b/spring/seata-spring-autoconfigure/seata-spring-autoconfigure-core/src/main/java/org/apache/seata/spring/boot/autoconfigure/loader/SeataPropertiesLoader.java index f747943f1c5..e5083b6a4f4 100644 --- a/spring/seata-spring-autoconfigure/seata-spring-autoconfigure-core/src/main/java/org/apache/seata/spring/boot/autoconfigure/loader/SeataPropertiesLoader.java +++ b/spring/seata-spring-autoconfigure/seata-spring-autoconfigure-core/src/main/java/org/apache/seata/spring/boot/autoconfigure/loader/SeataPropertiesLoader.java @@ -96,10 +96,15 @@ public void loadSessionAndLockModes() { Optional lockMode = invokeEnumMethod(storeConfigClass, "getEffectiveLockMode", "getName"); sessionMode.ifPresent(value -> System.setProperty("sessionMode", value)); lockMode.ifPresent(value -> System.setProperty("lockMode", value)); - } catch (ClassNotFoundException - | NoSuchMethodException - | InvocationTargetException - | IllegalAccessException e) { + } catch (InvocationTargetException e) { + Throwable cause = e.getCause(); + if (cause instanceof RuntimeException) { + throw (RuntimeException) cause; + } + if (cause instanceof Error) { + throw (Error) cause; + } + } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException e) { // The exception is not printed because it is an expected behavior and does not affect the normal operation // of the program. // StoreConfig only exists on the server side From b74a5a776733a05a15711ce62b142ab15fb1baf4 Mon Sep 17 00:00:00 2001 From: legendPei <804141866@qq.com> Date: Thu, 4 Jun 2026 11:18:46 +0800 Subject: [PATCH 06/19] feat(rocksdb): add store engine foundation --- dependencies/pom.xml | 6 + server/pom.xml | 4 + .../storage/rocksdb/RocksDBColumnFamily.java | 71 +++++ .../storage/rocksdb/RocksDBKeyCodec.java | 107 +++++++ .../storage/rocksdb/RocksDBLocalLocks.java | 116 ++++++++ .../storage/rocksdb/RocksDBStoreConfig.java | 63 +++++ .../storage/rocksdb/RocksDBStoreEngine.java | 226 +++++++++++++++ .../rocksdb/RocksDBStoreEngineFactory.java | 57 ++++ .../storage/rocksdb/RocksDBValueCodec.java | 130 +++++++++ .../store/RocksDBTransactionStoreManager.java | 260 ++++++++++++++++++ .../storage/rocksdb/RocksDBKeyCodecTest.java | 49 ++++ .../rocksdb/RocksDBLocalLocksTest.java | 35 +++ .../rocksdb/RocksDBStoreEngineTest.java | 108 ++++++++ .../rocksdb/RocksDBValueCodecTest.java | 51 ++++ .../RocksDBTransactionStoreManagerTest.java | 194 +++++++++++++ 15 files changed, 1477 insertions(+) create mode 100644 server/src/main/java/org/apache/seata/server/storage/rocksdb/RocksDBColumnFamily.java create mode 100644 server/src/main/java/org/apache/seata/server/storage/rocksdb/RocksDBKeyCodec.java create mode 100644 server/src/main/java/org/apache/seata/server/storage/rocksdb/RocksDBLocalLocks.java create mode 100644 server/src/main/java/org/apache/seata/server/storage/rocksdb/RocksDBStoreConfig.java create mode 100644 server/src/main/java/org/apache/seata/server/storage/rocksdb/RocksDBStoreEngine.java create mode 100644 server/src/main/java/org/apache/seata/server/storage/rocksdb/RocksDBStoreEngineFactory.java create mode 100644 server/src/main/java/org/apache/seata/server/storage/rocksdb/RocksDBValueCodec.java create mode 100644 server/src/main/java/org/apache/seata/server/storage/rocksdb/store/RocksDBTransactionStoreManager.java create mode 100644 server/src/test/java/org/apache/seata/server/storage/rocksdb/RocksDBKeyCodecTest.java create mode 100644 server/src/test/java/org/apache/seata/server/storage/rocksdb/RocksDBLocalLocksTest.java create mode 100644 server/src/test/java/org/apache/seata/server/storage/rocksdb/RocksDBStoreEngineTest.java create mode 100644 server/src/test/java/org/apache/seata/server/storage/rocksdb/RocksDBValueCodecTest.java create mode 100644 server/src/test/java/org/apache/seata/server/storage/rocksdb/store/RocksDBTransactionStoreManagerTest.java diff --git a/dependencies/pom.xml b/dependencies/pom.xml index 23a312cbe31..add33b46048 100644 --- a/dependencies/pom.xml +++ b/dependencies/pom.xml @@ -142,6 +142,7 @@ 3.1.10 4.12.0 2.4.0 + 10.10.1.1 0.12.3 @@ -600,6 +601,11 @@ native-lib-loader ${native-lib-loader.version} + + org.rocksdb + rocksdbjni + ${rocksdbjni.version} + javax.inject javax.inject diff --git a/server/pom.xml b/server/pom.xml index 9de1f407868..9b40d44da33 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -167,6 +167,10 @@ seata-metrics-all ${project.version} + + org.rocksdb + rocksdbjni +