FMDB 多线程使用

在App中保持一个FMDatabaseQueue的实例,并在所有的线程中都只使用这一个实例。

[FMDatabaseQueue databaseQueueWithPath:path];

FMDatabaseQueue虽然看似一个队列,实际上它本身并不是,它通过内部创建一个Serial的dispatch_queue_t来处理通过inDatabaseinTransaction传入的Blocks,所以当我们在主线程(或者后台)调用inDatabase或者inTransaction时,代码实际上是同步的。FMDatabaseQueue这么设计的目的是让我们避免发生并发访问数据库的问题,因为对数据库的访问可能是随机的(在任何时候)、不同线程间(不同的网络回调等)的请求。内置一个Serial队列后,FMDatabaseQueue就变成线程安全了,所有的数据库访问都是同步执行,而且这比使用@synchronizedNSLock要高效得多。

但是这么一来就有了一个问题:如果后台在执行大量的更新,而主线程也需要访问数据库,虽然要访问的数据量很少,但是在后台执行完之前,还是会阻塞主线程。 
对此:

  1. 如果你是在后台使用的inDatabase来执行更新,可以考虑换成inTransaction,后者比前者更新起来快很多,特别是在更新量比较大的时候(比如更新1000条或10000条)。
  2. 拆解你的更新数据量,如果有300条,可以分10次、每次更新30条。当然有时不能这么做,因为你可能通过网络请求回来的数据,你希望一次性、完整地写入到数据库中,虽然有局限性,不过这确实能很好地减少每个Block占用数据库的时间。
  3. 上面两点可以改善问题,但是问题依然是存在的,在大多数时候,你应该把从主线程调用inDatabaseinTransaction放在异步里:
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [self.databaseQueue inDatabase:^(FMDatabase *db) {
            //do something...
        }];
    });
  4. 这种方式能解决不依赖于数据库返回的结果的情况,如果对返回结果有依赖,就需要考虑UI上的体验了,如加一个UIActivityIndicatorView
时间: 2024-10-24 12:10:37

FMDB 多线程使用的相关文章

转发 FMDB多线程下"is currently in use" 或者 "database is locked" 问题

FMDB多线程下"is currently in use" 或者 "database is locked" 问题 问题一: "is currently in use" 出现的场景是这样的,多线程操作数据库,每个线程都使用了FMDatabase实例(注意没有使用FMDatabaseQueue). 问题二:“database is locked"出现的场景是这样的,多线程操作数据库,每个线程各自创建了FMDatabaseQueue实例操作数

FMDB多线程下"is currently in use" 或者 "database is locked" 问题

问题一: "is currently in use" 出现的场景是这样的,多线程操作数据库,每个线程都使用了FMDatabase实例(注意没有使用FMDatabaseQueue). 问题二:“database is locked"出现的场景是这样的,多线程操作数据库,每个线程各自创建了FMDatabaseQueue实例操作数据库,或者一个线程创建FMDatabaseQueue实例来操作,而另外的线程创建了FMDatabase实例来操作. 解决:FMDB多线程操作数据库,必须使

使用FMDB多线程访问数据库,及database is locked的问题

今天终于解决了多线程同时访问数据库时,报数据库锁定的问题,错误信息是: Unknown error finalizing or resetting statement (5: database is locked) 最后通过FMDatabaseQueue解决了这个问题,本文总结一下: FMDatabase不能多线程使用同一个实例 多线程访问数据库,不能使用同一个FMDatabase的实例,否则会发生异常.如果线程使用单独的FMDatabase实例是允许的,但是同样有可能发生database is

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

原理:文件数据库sqlite,同一时刻允许多个进程/线程读,但同一时刻只允许一个线程写.在操行写操作时,数据库文件被琐定,此时任何其他读/写操作都被阻塞,如果阻塞超过5秒钟(默认是5秒,能过重新编译sqlite可以修改超时时间),就报"database is locked"错误. 所以,在操作sqlite时,应该即时关闭连接:打开连接后,尽量减少非常费时的操作. 多线程同时访问数据库时,报数据库锁定的问题,错误信息是: Unknown error finalizing or reset

FMDB实现增删改查

先用cocoapods安装FMDB,然后在控制器里引入FMDB //创建数据库路径    NSString *doc = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];        NSString *filePath = [doc stringByAppendingPathComponent:@"db.sqlite"];        //创建数据库    FMD

FMDB的线程安全

最近面试被问到FMDB的多线程处理问题,因为之前项目中是移植别人的代码,没有踩过这里的坑. 问题: 多线程同时访问数据库时,报数据库锁定的问题,错误信息是: Unknown error finalizing or resetting statement (5: database is locked) 原因: 文件数据库sqlite,同一时刻允许多个进程/线程读,但同一时刻只允许一个线程写.在操行写操作时,数据库文件被琐定,此时任何其他读/写操作都被阻塞,如果阻塞超过5秒钟(默认是5秒,能过重新编

FMDB事务的使用

http://blog.csdn.net/qq_29892943/article/details/50541439 首先,说一下事务是什么,比如说我们有一个学生表和一个学生成绩表,而且一个学生对应一个学生成绩.比如小明的成绩是100分,那么我们要写两个sql语句对不同的表进行插入数据.但是如果在这个过程中,小明这个学生成功的插入到数据库,而成绩插入时失败了,怎么办?这时事务就突出了它的作用.用事务可以对两个表进行同时插入,一旦一个表插入失败,那么就会进行事务回滚,就是让另一个表也不进行插入数据了

iOS中 FMDB第三方SQLite数据库 UI_20

1.什么是FMDB? FMDB是iOS平台下SQLite数据库,只不过它是OC方式封装了C语言的SQLite语句,使用起来更加面向对象 2.FMDB的优点:1.使用起来更加面向对象; 2.对比苹果自带的 Core Data 数据管理工具更加的轻量级,更加的灵活,而且FMDB支持跨平台; 3.提供多线程下的数据安全保护机制,有效地防止数据混乱 3.FMDM中重要的类: FMDBDataBase: 它代表一个数据库对象,(我们需要创建数据库对象时就使用这个类) FMDBDataBaseQueue:

FMDB 使用方法

优秀的第三方库,README 也是很优秀的,理解了 README,会对使用带来很多便利. ARC 和 MRC 项目中使用 ARC 还是 MRC,对使用 FMDB 都没有任何影响,FMDB 会在编译项目时自动匹配. 使用 在 FMDB 中有三个重要的类: FMDatabase:是一个提供 SQLite 数据库的类,用于执行 SQL 语句. FMResultSet:用在 FMDatabase 中执行查询的结果的类. FMDatabaseQueue:在多线程下查询和更新数据库用到的类. 数据库创建 F