在两个线程中并发执行两个SQLite事务

时间:2011-07-25 11:39:47

标签: android multithreading sqlite transactions ormlite

我的Android应用程序中有一定的更新方法,可生成大量数据 - 最多可达数百个数据库条目。 除了UI线程之外,我还有一个后台服务。两个线程都必须执行更新方法,有时甚至是在同一时间 - 基本上,这是关于生成和缓存要显示的数据。 UI和后台服务都需要这些数据。

目前,我已将方法的执行包装在ORMLite事务中,该事务映射到普通的SQLite事务。但是,有一天,当一些竞争条件搞砸了数据缓存时,我担心这会让我陷入困境。

问题:SQLite事务是否可以保护我免受并发执行的影响,还是应该实现某种工作线程,这种线程在生成器方法启动时生成,或者阻塞生成器方法是否已经运行?

更新

我决定不依赖SQLite逻辑来保护我的高级Java方法。解决方案对我来说如下:

  • 使用synchronized
  • 包装方法的生成部分
  • 引入一个跟踪上次执行方法的变量(在方法结束时设置,因此它是执行END的标记)
  • synchronized部分中的第一件事,检查上次执行是否在特定阈值(例如,过去的< = 100ms)
    • 如果是,请跳过生成
    • 如果不是,请执行生成

这样,不应该进行重复生成,因为当同时从两个线程访问该方法时,第一个将生成,但第二个不生成。对我来说最重要的部分是它仍然是阻塞的,因为两个线程都依赖于在调用方法之后发生的一代。

1 个答案:

答案 0 :(得分:0)

修改

在我的下面的陈述中似乎我错了:根据许多人的说法,SQLite实现是线程安全的。但是,我遇到了严重的线程问题,特别是在测试数据库访问时,但这必定是由我的代码中的其他因素引起的,我认为。

对于误导性的回答感到抱歉。

<强> ORIGIN:

好问题!

这里你应该非常小心因为标准的Android数据库访问对象(例如SQLiteDatabaseCursor等)默认情况下不是线程安全的。除非你明确地用多线程编写它们,否则ContentProvider似乎不会给你一个完整的保护。

根据ContentProvider上的Android documentation和线程(几乎在页面末尾):

  

“因为这些方法[update()是其中一个函数]可能同时从任意数量的线程调用,所以它们也必须实现为线程安全的。”

我不知道SQLiteDatabases是否有任何明确的锁定机制(如锁定实际的数据库文件)。我假设一个事务本身会锁定,至少是你访问数据库的句柄。我不知道你的数据库有多个句柄的情况是什么。

也许您可以尝试实现一些单例对象(可能是ContentProvider?)来访问您的数据库,但即使这样,您也必须管理某种“请求队列”。

您还应该考虑 not 从UI线程对文件系统(数据库在文件系统上)进行任何调用,无论如何。无法保证数据库能够及时回答并且您可能最终得到ANR(特别是当您编写"...which generates quite an amount of data"时)。