SQLite同时读写

Hig*_*yer 24 database sqlite multithreading android

我已经阅读了很多主题,但无法找出问题的答案:是否可以同时读写?

我有后台线程更新一些数据,UI需要存储在DB中的小块数据.因此在UI线程中执行SELECT操作.但它会在更新过程中阻止.结果,UI冻结了几秒钟.

写作时有没有人能从DB中读取成功?


它可以在iPhone上读写DB.这种差异的原因是在本机sqlite函数上同步实现包装吗?

Ema*_*lin 57

在Android 3.0及更高版本上,SQLiteDatabases支持WAL模式(预写日志记录):

如果未启用预写日志记录(默认值),则无法同时在数据库上进行读写操作.在修改数据库之前,writer会隐式获取数据库上的独占锁,这会阻止读者在写入完成之前访问数据库.

相反,当启用预写日志记录时,写操作发生在单独的日志文件中,该文件允许读取同时进行.当写入正在进行时,其他线程上的读者将在写入开始之前感知数据库的状态.当写入完成时,其他线程上的读者将会感知数据库的新状态.

http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#enableWriteAheadLogging()

要在WAL模式下启动事务,请使用beginTransactionNonExclusive()而不是beginTransaction().当beginTransaction()以EXCLUSIVE模式启动事务时,beginTransactionNonExclusive()以IMMEDIATE模式启动一个事务

简单来说:为IMMEDIATE模式调用beginTransactionNonExclusive(),我们可以在另一个线程正在写入时读取(写入事务开始之前的状态,因为我们不会使用read_uncommitted连接 - > http://en.wikipedia.org/wiki/ Isolation_%28database_systems%29#Dirty_reads).

  • API 11 on(Honeycomb)支持WAL模式.API 11和API 16之间的区别在于您可以使用Context.MODE_ENABLE_WRITE_AHEAD_LOGGING模式实际使用API​​ 16在WAL模式下打开数据库,同时您必须在API11-15中的一个可用模式中打开它,然后切换到WAL模式使用SQLiteDatabase.enableWriteAheadLogging().在WAL模式下打开速度要快得多,但这就是你得到的.在Honeycomb之前,没有WAL模式意味着应用程序将运行得更慢,但"应该"至少没有其他副作用. (8认同)