Microstream中如何正确使用BinaryHandler存储易失long类型数组
问题根因
你遇到的问题本质是Microstream默认的持久化逻辑只检测对象字段的引用变化,不会自动感知引用不变的对象内部内容变更:
- 往
PersistableLongArrayList中添加元素时,如果没有触发数组扩容,items字段的数组引用不会发生变化 - 调用
storage.store(t.root)时,Microstream检测到size是基础类型,值发生变化就会更新;但items字段的引用无变化,就不会重新序列化数组,导致新增的元素值没有被持久化 - 重启后加载到的
size是最新值,但数组对应位置的值还是旧的0,就出现了你观测到的现象
修复方案
需要修改两处配置:
- 将自定义TypeHandler中
items字段的声明改为可变字段,告诉Microstream就算该字段的引用不变,也要持久化其内部更新的内容 - 启动存储实例时主动注册你自定义的TypeHandler,否则你的持久化规则不会生效
第一步:修改PersistableLongArrayList的TypeHandler定义
public class PersistableLongArrayList extends LongArrayList { static BinaryTypeHandler<PersistableLongArrayList> provideTypeHandler() { return Binary.TypeHandler(PersistableLongArrayList.class, Binary.Field_int( "size", list -> list.size, (list, value) -> list.size = value ), // 改用Field_mutable声明该字段是内部可变的 Binary.Field_mutable( long[].class, "items", list -> list.items, (list, value) -> list.items = value ) ); } }
第二步:启动存储时注册自定义TypeHandler
private EmbeddedStorageManager startDB() { // 构建自定义配置,注册你写的类型处理器 EmbeddedStorageConfiguration config = EmbeddedStorage.Configuration() .registerTypeHandler(PersistableLongArrayList.provideTypeHandler()) .createConfiguration(); EmbeddedStorageManager storageManager = EmbeddedStorage.start(config); if(storageManager.root() == null) { PersistableLongArrayList list = new PersistableLongArrayList(); storageManager.setRoot(list); storageManager.storeRoot(); root = list; } else { root = (PersistableLongArrayList)storageManager.root(); } return storageManager; }
修改完成后重新运行测试,多次执行后列表就会按预期逐步增长为[1,2,3,4]。
内容的提问来源于stack exchange,提问作者Thomas
相关产品推荐
相关产品推荐

