SQLITE_IOERR_LOCK(disk I/O error code 3850)

最近发现app线上版本出现下面这个崩溃,下面是崩溃堆栈

通过查看sqlite官方文档,原来是一种锁异常,是由多线程访问数据库导致的异常,由于sqlite是简单的文件数据库,我设计的数据库只有一个xxx.db文件,其中包含多个表,每一个表由一个数据库Dao封装来进行curd操作,虽然单个Dao的curd做了线程同步,但是当多线程时,多个Dao操作数据库文件也会抛出这个异常。下面来看原文档截图

sqlite_lock_type

sqlite_lock_type

在一个线程中sqlite数据库文件有五种锁定状态:

unlocked

数据库没有加锁的状态。数据库既没有读也没有写。任何内部缓存的数据都被认为是可疑的需要被验证之后才可以使用。其他的线程可以以被允许的状态进行数据库读写操作。这是数据库的默认状态。

SHARED

数据库可以读但是不能写,任何其他的线程都可以同时获得一个SHARED locks(共享锁),所以可能同时有很多读者,但是当有一个或多个共享锁的时候,不允许其他线程或者进程写入数据库。

RESERVED

RESERVED lock的意思是进程计划在将来的某个时刻写入数据库文件但是当前数据库处于正在读的状态(shared lock)。尽管多个SHARED lock可以喝一个RESERVED lock同时存在,但是在同一时刻只允许有一个RESERVED lock。RESERVED lock和PENGDING lock的区别在于,当数据库被RESERED lock锁定的时候可以继续获得SHARED lock。

PENDING

PENDING lock意思是进程持有锁想要尽快对数据库进行写操作但是需要等到当前所有的SHARED lock被清除才能进一步的获得EXCLUSIVE lock。如果有一个激活状态的PENGDING lock那么新的SHARED lock申请将会被拒绝,但是已经存在的SHARED lock还是会被允许继续。

EXCLUSIVE

EXCLUSIVE lock(排他锁)正式写入数据库的时候启用排他锁。一个数据库文件仅仅只有一个EXCLUSIVE lock被允许,没有任何其他类型的锁与之共存。为了提高并发,SQLite只持有EXCLUSIVE锁很短的时间。



  copyright@黑月神话,转载请注明出处:vjson.com

SQLITE_IOERR_LOCK(disk I/O error code 3850)》上有1条评论

发表评论