Android Lollipop 5.0.1 SQLiteLog POSIX错误11 SQLite错误:3850

Lui*_*tni 21 sqlite multithreading android posix android-5.0-lollipop

我在升级应用程序以支持Android Lollipop时遇到问题.该应用程序实现了一个SyncAdapter,它通过内容提供程序在数据库上写入.同时,用户正在浏览应用程序的前端,其中加载程序从数据库中读取相同的数据.加载程序还可以监听数据更改.

现在,如果我在前Lollipop设备上运行该程序,一切正常,没有任何错误输出.

在Lollipop上,我收到以下logcat消息:

11:20:59.344  22341-22376/com.example.com E/SQLiteLog? (10) POSIX Error : 11 SQLite Error : 3850
11:20:59.364  22341-22376/com.example.com E/SQLiteLog? (10) POSIX Error : 11 SQLite Error : 3850
11:20:59.364  22341-22376/com.example.com E/SQLiteLog? (10) POSIX Error : 11 SQLite Error : 3850
11:20:59.364  22341-22376/com.example.com E/SQLiteLog? (10) POSIX Error : 11 SQLite Error : 3850
Run Code Online (Sandbox Code Playgroud)

现在,来自SQLite文档:

(3850)SQLITE_IOERR_LOCK

SQLITE_IOERR_LOCK错误代码是SQLITE_IOERR的扩展错误代码,表示咨询文件锁定逻辑中的I/O错误.通常SQLITE_IOERR_LOCK错误表示获取PENDING锁定时出现问题.但是,它也可以指示Mac上使用的某些专用VFS上的各种锁定错误.一切似乎都在高水平上正常工作(即执行读取和写入)

和:

PENDING锁意味着持有锁的进程想要尽快写入数据库,并且只是等待所有当前的SHARED锁清除,以便它可以获得EXCLUSIVE锁.如果PENDING锁处于活动状态,则不允许对数据库使用新的SHARED锁,但允许继续使用现有的SHARED锁.

我知道SQLite版本已经被Lollipop中的几个主要版本更新了,所以我很容易认为错误是由于我无法隔离的SQLite的一些新行为.

但是,从更高级别的角度看,一切似乎都运行良好(App不会崩溃,执行读写操作,帧率不会下降 - 至少对人眼来说)但我不想忽略这个问题发布应用程序,直到我确定它不会导致数据损坏或麻烦.

也许我对棒棒糖关于锁和多进程数据库访问的一些重要更改缺失了,但我觉得这是一个关于Art/Dalvik域的较低级别的问题,因此必须在NDK上下文中修复.

有没有办法解决这个问题而不分发特定版本的SQLite?是否有任何清单/ SQLite选项来避免错误?

提前致谢

BJo*_*vke 2

Writer 锁定数据库的读取和写入。这意味着它必须等待所有读者完成并释放锁才能获得锁。

写入者请求锁后,新的读取者锁必须等待写入者先获取锁,然后释放锁。

这可能是您的解决方案:WAL 模式

激活和配置 WAL 模式:

SQLite 数据库连接默认为journal_mode=DELETE。要转换为 WAL 模式,请使用以下编译指示:

PRAGMA journal_mode=WAL;
Run Code Online (Sandbox Code Playgroud)

WAL 在写入时不会阻塞读取器,这也意味着写入器不需要等待当前读取锁被释放。

WAL 所需的最低 SQLite 版本是 3.7.0 (2010-07-21)。Lollipop 5.0 使用 SQLite 3.8.4.3,因此 WAL 应该可供您使用。

但是WAL在低于3.0的Android版本中不存在,尽管有一些例外。看看Android中使用的SQLite版本?。如果您不需要应用程序在 Android 3.0 以下运行,您可以使用 WAL。