【问题标题】:Is it OK to keep a read transaction open for a long time in SQLite?在 SQLite 中长时间保持读取事务打开是否可以?
【发布时间】:2016-07-15 09:20:04
【问题描述】:

读取交易:https://www.sqlite.org/isolation.html

我们假设 WAL 已启用,因此我们可以在一个线程中读取,而另一个线程正在写入。


我想要实现的是这样的。

我有两个线程,一个是 UI 线程,有时执行数据库读取,另一个是数据库线程,在事务中执行数据库读取/写入。

UI 线程中的结果被缓存,有时信息不完整,比如对于一个事物列表,我们只查询列表的大小,或者只查询该查询的前 10 个项目,然后我们在 UI 时增量加载到达那部分。

在 db 线程上,我们将执行事务并记住所有更改,然后将更改发布(UI 线程是一个 Looper 线程)到 UI 线程并逐步更新 UI 缓存,以便它尽可能少地阻塞 UI 线程.

问题是当 db 事务完成时,UI 线程可能会在 Looper 线程处理该消息之前触发 UI 线程上的 DB 读取,同样由于 UI 框架的一些限制,我们无法更新缓存,因为UI 线程当前正在使用它。

所以我的想法是在 UI 线程上,在任何查询发生之前,开始一个读取事务(在延迟模式下开始一个事务,并且这个事务不会因为没有写入而锁定数据库),然后任何读取发生在UI线程会发生在这个事务中,然后looper线程得到更新信息,结束事务,更新缓存,开始下一个事务。所以数据库和缓存在 UI 线程中被转换为新的状态并同步。


那么我可以长时间保持读取事务打开吗?

【问题讨论】:

    标签: java android multithreading sqlite transactions


    【解决方案1】:

    所有的读取都在一个事务中完成(如果需要,一个自动的),所有的事务都会锁定数据库。但是,WAL 模式下的只读锁仅阻止 checkpoint operations

    长时间有一个活跃事务是没有问题的,只要不断增长的WAL文件不会溢出磁盘。 如果您的应用程序需要事务才能正常工作,那么您别无选择 - 替代方案是手动实现一些类似的事务机制,最好让数据库处理。

    【讨论】:

    • 可能不会。但可以肯定的是,你必须衡量。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-23
    • 2022-07-27
    • 2021-05-11
    • 2021-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多