FMDB的线程安全

最近面试被问到FMDB的多线程处理问题,由于以前项目中是移植别人的代码,没有踩过这里的坑。html

问题:

多线程同时访问数据库时,报数据库锁定的问题,错误信息是:面试

Unknown error finalizing or resetting statement (5: database is locked)sql

缘由:

文件数据库sqlite,同一时刻容许多个进程/线程读,但同一时刻只容许一个线程写。在操行写操做时,数据库文件被琐定,此时任何其余读/写操做都被阻塞,若是阻塞超过5秒钟(默认是5秒,能太重新编译sqlite能够修改超时时间),就报"database is locked"错误。因此,在操做sqlite时,应该即时关闭链接;打开链接后,尽可能减小很是费时的操做。数据库

 

解决:

FMDatabase **不能多线程使用一个实例多线程访问数据库,不能使用同一个**FMDatabase 的实例。不然会发生异常。若是线程使用单独的FMDatabase 实例是容许的,可是一样有可能发生database is locked的问题。这是因为多线程对sqlite的竞争引发的.多线程

 

FMDatabaseQueue 解决这个问题的思路是:建立一个队列(串行线程队列),而后将放入的队列的block顺序执行,这样避免了多线程同时访问数据库线程

解决方案 共享同一个FMDatabaseQueue**实例**orm

 

注意:sqlite

本来使用FMDatabase类,须要手工调用db的open和close方法,可是用FMDatabaseQueue,不须要调用open,由于查看代码发现,Queue已经open了。htm

因此,使用Queue,是不须要本身打开和关闭db的。可是若是使用了FMResultSet,rs却是须要关闭,不然会报warning:
if ([db hasOpenResultSets]) {
NSLog(@"Warning: there is at least one open result set around after performing [FMDatabaseQueue inDatabase:]");
队列

 

引伸阅读

加入GCD信号量控制

Reference:

IOS 使用FMDB多线程访问数据库 及databaseislocked的问题

相关文章
相关标签/搜索