android - 在 Android 上使用 SQLite 时如何避免并发问题?

标签 android database sqlite

在 Android 应用中对 SQLite 数据库执行查询时,最佳做法是什么?

从 AsyncTask 的 doInBackground 运行插入、删除和选择查询是否安全?还是我应该使用 UI 线程?我认为数据库查询可能很“繁重”并且不应该使用 UI 线程,因为它可以锁定应用程序 - 导致 Application Not Responding (ANR)。

如果我有多个 AsyncTask,它们应该共享一个连接还是应该各自打开一个连接?

这些场景有什么最佳实践吗?

最佳答案

插入、更新、删除和读取通常可以从多个线程进行,但 Brad 的 answer是不正确的。您必须小心创建和使用连接的方式。在某些情况下,即使您的数据库没有损坏,更新调用也会失败。

基本答案。

SqliteOpenHelper 对象保持一个数据库连接。它似乎为您提供了读写连接,但实际上并没有。调用只读,无论如何都会得到写数据库连接。

所以,一个辅助实例,一个数据库连接。即使您从多个线程中使用它,一次一个连接。 SqliteDatabase 对象使用 java 锁来保持访问序列化。因此,如果 100 个线程有一个 db 实例,则对实际磁盘数据库的调用会被序列化。

所以,一个助手,一个数据库连接,在java代码中序列化。一个线程,1000 个线程,如果您使用它们之间共享的一个帮助程序实例,那么您所有的数据库访问代码都是串行的。生活是美好的(ish)。

如果您尝试同时从实际的不同连接写入数据库,则会失败。它不会等到第一个完成后再写入。它根本不会写你的改变。更糟糕的是,如果您没有在 SQLiteDatabase 上调用正确版本的插入/更新,您将不会得到异常。您只会在 LogCat 中收到一条消息,就是这样。

那么,多线程?使用一名助手。时期。如果您知道只有一个线程在写入,您可能可以使用多个连接,并且您的读取速度会更快,但买家要小心。我没有测试那么多。

这是一篇包含更多详细信息和示例应用的博文。

Gray 和我实际上正在整理一个基于他的 Ormlite 的 ORM 工具,该工具可与 Android 数据库实现原生配合使用,并遵循我在博文中描述的安全创建/调用结构。那应该很快就出来了。看看吧。


同时,还有一篇后续博文:

同样检查前面提到的锁定示例的 2point0 的 fork :

关于android - 在 Android 上使用 SQLite 时如何避免并发问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2493331/

相关文章:

android - 操作栏图标未显示在 android 操作栏中

php - 在 MYSQL 数据库中存储多语言/unicode 字符(泰语、印地语、菲律宾语)

c - SQLite 和 C 的第一步

iphone - 如何将动态 NSNumber 对象绑定(bind)到 SQLite 查询?

mysql - 在本地主机上的 sqlite3 上转换 Rails 项目

Travis CI 上的 javax.net.ssl.SSLHandshakeException

android - 如何将对象从子 Activity 传递到主 Activity ?

单个对话框中的 Android 多个运行时权限

sql-server - 如何测量Azure sql server数据库中用户消耗的数据?

sql-server - 数据库图(ER 图/表格布局)在衡量某些事物的分布时会是什么样子?