【问题标题】:How to correctly handle sqlite queries in different threads?如何正确处理不同线程中的 sqlite 查询?
【发布时间】:2018-05-05 13:03:58
【问题描述】:

我正在开发一个使用 sqlite 数据库的 iPhone 应用程序。该应用程序在主线程中使用 UI 在后台线程中从 Internet 下载数据。后台下载线程可以对数据库执行 INSERT、UPDATE 和 SELECT。 UI 层还可以通过执行 UPDATE 和 SELECT 与数据库进行交互。如果在后台线程下载时我没有与 UI 进行大量交互,那么一切正常。但是,当下载正在进行时,在主 (UI) 线程上执行大量更新时,我开始遇到问题。

在对数据库的每个查询中,我都使用@synchronized 语句,但这并不能解决问题。当查询(来自 UI 和来自后台线程)同时执行时,会导致数据丢失。在主线程中更新数据也可以像在后台一样执行(如果它们彼此分开执行)。

数据库有 sqlite3_threadsafe() == 2; 对于所有查询,我正在使用一个连接,可能问题隐藏在此?

【问题讨论】:

  • 为什么要手写SQL?使用 FMDB 或其他一些包装器。他们通常也有不错的三个文档。更好的是,使用核心数据。它具有出色的线程模型。
  • 我只是继续开发它,另一个开发者做到了。

标签: objective-c database multithreading performance sqlite


【解决方案1】:

根据the docs,您应该调用sqlite3_config() 函数并选择线程模型。我建议先尝试 SQLITE_CONFIG_SERIALIZED。

还要确保您不要将 SQLITE_OPEN_NOMUTEX 标志用于sqlite3_open_v2()

一般来说,一个好的做法是将所有写入序列化到单个线程。一种“一个作家 - 许多读者”的模式。我建议甚至避免来自主线程的所有数据库访问,尽管这可能会很复杂,具体取决于您拥有的遗留代码的数量。

【讨论】:

    【解决方案2】:

    SQLite 的线程模式仅保护单个函数调用。但是,每个连接都有一个事务,因此如果您有多个线程同时访问数据库,它们仍然会相互干扰。 您应该改用多个连接。

    如果你想同时读写,考虑使用WAL mode

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-24
      • 2022-07-11
      • 2021-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多