You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Spring Boot集成MicroStream始终加载初始版本数据?

问题:Spring Boot集成MicroStream后数值无法持久化更新

我在Spring Boot中使用MicroStream编写测试示例:首次启动时创建DemoSession对象并存储到嵌入式存储;第二次启动加载该对象后将其numValue属性自增1,但后续每次启动加载的numValue始终为0。transaction*slt文件每次运行都会增大,看起来新值似乎被加载,但根对象每次启动都处于初始状态。

示例代码

package test.microstream;

import jakarta.annotation.PostConstruct;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import one.microstream.integrations.spring.boot.types.Storage;
import one.microstream.storage.types.StorageManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

import java.util.HashMap;
import java.util.Map;

@SpringBootApplication
@Slf4j
public class MicrostreamApplication {

    public static void main(String[] args) {
        SpringApplication.run(MicrostreamApplication.class, args);
    }

    @AllArgsConstructor
    @Data
    @ToString
    public static class DemoSession {
        String account;
        int numValue;
    }

    @Data
    @ToString
    @Storage
    public static class DemoStorage {
        Map<String, DemoSession> sessions;

        @PostConstruct
        public void init() {
            if(sessions == null) {
                sessions = new HashMap<>();
            }
        }

        public void setSession(DemoSession session) {
            sessions.put(session.getAccount(), session);
        }

        public DemoSession getSession(String account) {
            return sessions.get(account);
        }
    }

    @Autowired
    DemoStorage storage;

    @Autowired
    StorageManager storageManager;

    @Bean
    public ApplicationRunner runner() {
        return new ApplicationRunner() {
            @Override
            public void run(ApplicationArguments args) throws Exception {
                log.info("root {}", storageManager.root());
                log.info("storage {}", storage);
                var session = storage.getSession("acc");
                if(session == null) {
                    session = new DemoSession("acc", 0);
                    log.info("create session {}", session);
                    storage.setSession(session);
                    storageManager.storeRoot();
                } else {
                    log.info("loaded session {}", session);
                    session.setNumValue(session.getNumValue()+1);
                    log.info("update session {}", session);
                    storageManager.storeRoot();
                }
                log.info("after all");
                log.info("root {}", storageManager.root());
                log.info("storage {}", storage);
            }
        };
    }
}

程序运行输出

2023-02-14T21:35:32.947+01:00  INFO 163817 --- [           main] one.microstream.util.logging.Logging     : MicroStream Version 08.00.00-MS-EA2
2023-02-14T21:35:33.089+01:00  INFO 163817 --- [           main] .s.e.t.EmbeddedStorageFoundation$Default : Creating embedded storage manager
2023-02-14T21:35:33.206+01:00  INFO 163817 --- [           main] .t.PersistenceTypeHandlerManager$Default : Initializing type handler manager
2023-02-14T21:35:33.266+01:00  INFO 163817 --- [           main] o.m.s.e.t.EmbeddedStorageManager$Default : Starting embedded storage manager
2023-02-14T21:35:33.268+01:00  INFO 163817 --- [           main] o.m.storage.types.StorageSystem$Default  : Starting storage system
2023-02-14T21:35:33.269+01:00  INFO 163817 --- [           main] .m.s.t.StorageStructureValidator$Default : Storage structure validated successfully.
2023-02-14T21:35:33.295+01:00  INFO 163817 --- [           main] .t.PersistenceTypeHandlerManager$Default : Initializing type handler manager
2023-02-14T21:35:33.308+01:00  INFO 163817 --- [           main] o.m.s.e.t.EmbeddedStorageManager$Default : Embedded storage manager initialized
2023-02-14T21:35:33.366+01:00  INFO 163817 --- [           main] t.microstream.MicrostreamApplication     : Started MicrostreamApplication in 0.963 seconds (process running for 1.278)
2023-02-14T21:35:33.367+01:00  INFO 163817 --- [           main] t.microstream.MicrostreamApplication     : root MicrostreamApplication.DemoStorage(sessions={acc=MicrostreamApplication.DemoSession(account=acc, numValue=0)})
2023-02-14T21:35:33.367+01:00  INFO 163817 --- [           main] t.microstream.MicrostreamApplication     : storage MicrostreamApplication.DemoStorage(sessions={acc=MicrostreamApplication.DemoSession(account=acc, numValue=0)})
2023-02-14T21:35:33.367+01:00  INFO 163817 --- [           main] t.microstream.MicrostreamApplication     : loaded session MicrostreamApplication.DemoSession(account=acc, numValue=0)
2023-02-14T21:35:33.367+01:00  INFO 163817 --- [           main] t.microstream.MicrostreamApplication     : update session MicrostreamApplication.DemoSession(account=acc, numValue=1)
2023-02-14T21:35:33.367+01:00  INFO 163817 --- [           main] .t.PersistenceTypeHandlerManager$Default : Initializing type handler manager
2023-02-14T21:35:33.372+01:00  INFO 163817 --- [           main] t.microstream.MicrostreamApplication     : after all
2023-02-14T21:35:33.372+01:00  INFO 163817 --- [           main] t.microstream.MicrostreamApplication     : root MicrostreamApplication.DemoStorage(sessions={acc=MicrostreamApplication.DemoSession(account=acc, numValue=1)})
2023-02-14T21:35:33.372+01:00  INFO 163817 --- [           main] t.microstream.MicrostreamApplication     : storage MicrostreamApplication.DemoStorage(sessions={acc=MicrostreamApplication.DemoSession(account=acc, numValue=1)})
2023-02-14T21:45:18.225+01:00  INFO 163817 --- [ionShutdownHook] o.m.storage.types.StorageSystem$Default  : Stopping storage system
2023-02-14T21:45:18.227+01:00  INFO 163817 --- [ionShutdownHook] o.m.storage.types.StorageSystem$Default  : Storage system stopped

依赖配置

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>one.microstream</groupId>
            <artifactId>microstream-storage-embedded</artifactId>
            <version>08.00.00-MS-EA2</version>
        </dependency>
        <dependency>
            <groupId>one.microstream</groupId>
            <artifactId>microstream-integrations-spring-boot3</artifactId>
            <version>08.00.00-MS-EA2</version>
        </dependency>
        <dependency>
            <groupId>one.microstream</groupId>
            <artifactId>microstream-storage-embedded-configuration</artifactId>
            <version>08.00.00-MS-EA2</version>
        </dependency>

    </dependencies>

解决方案

问题根源

MicroStream的持久化规则是:只有新添加到根对象引用链中的对象,或者明确调用store()方法的对象才会被持久化。你修改了DemoSession的numValue后,仅调用storageManager.storeRoot(),但DemoSession是已存在的对象,根对象DemoStorage对它的引用没有变化,因此MicroStream不会自动将修改后的实例写入存储。transaction文件变大只是因为写入了根对象的重复状态,并未实际保存DemoSession的更新值。

修复步骤

在更新DemoSession的numValue后,调用storageManager.store(session)来明确存储修改后的实例:

else {
    log.info("loaded session {}", session);
    session.setNumValue(session.getNumValue()+1);
    log.info("update session {}", session);
    storageManager.store(session); // 新增该行,持久化修改后的Session对象
    storageManager.storeRoot();
}

补充说明

如果有多个Session对象需要更新,也可以使用storageManager.storeAll(storage.getSessions().values())批量存储,但单独存储修改后的对象性能更优。

内容的提问来源于stack exchange,提问作者bit wheeze

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 06:24:35