问题现象
分别在Electron的主进程
和渲染进程
中使用了Lowdb读写同一份文件的数据。
例如,渲染进程首先写入数据文件,查看数据文件后确认数据已成功写入文件。在渲染进程成功写入数据后,主进程再读取相同数据文件,未能读取到刚才渲染进程写入的数据。此时,如果主进程再向文件写入数据,那么文件内的数据将被主进程的数据替换,渲染进程写入的数据被清除了。
问题分析
查阅Lowdb的官方文档,对数据读写有需要使用read()
和write()
方法。
对于write()
方法,其说明是在写入文件时,如果只使用value()
方法,将不会改变数据库的状态(state),也就是说,在调用write()
方法之前,数据还未能真正被持久化。这点在开发时倒是已经注意了。
但是之前倒是没能注意到state这个概念,那么是不是说明,进程间的数据,对于掌握的数据库的状态(state)是有不同。那么,是不是同样在读取数据库数据之前,也需要进行read()
操作,将当前进程的状态(state)更新,而后读取的数据也将一致?但是官方对于read()
方法没有过多的说明,不过从其示例来看,确实read()
方法会更新状态(state)。
db.read()
Reads source using storage.read option (depending on the adapter, may return a promise).
1
2
3
4
5
6
7// With lowdb/FileSync
db.read()
console.log('State has been updated')
// With lowdb/FileAsync
db.read()
.then(() => console.log('State has been updated'))
而后参考基于Electron开发Hosts切换工具的“踩坑”之旅,基本确定在进程间使用Lowdb时,读取数据前,需要使用read()
方法,来保证数据的一致性。
否则将只是对内存中的数据进行读取,单进程时因为有write()
,所以数据被写入到了文件中,但读取时,其实还是读取的内存数据,因为是单进程,所以数据库状态(state)不一致的问题不会显现出来。
解决方案
在数据读取前,需先使用read()
来更新当前进程数据库的状态(state)。
在数据写入后,需先使用write()
来更新当前进程数据库的状态(state)。
参考
https://lequ7.com/ji-yu-Electron-kai-fa-Hosts-qie-huan-gong-ju-de-cai-keng-zhi-lv.html