原理:文件数据库sqlite,同一时刻允许多个进程/线程读,但同一时刻只允许一个线程写。在操行写操作时,数据库文件被琐定,此时任何其他读/写操作都被阻塞,如果阻塞超过5秒钟(默认是5秒,能过重新编译sqlite可以修改超时时间),就报"database is locked"错误。

所以,在操作sqlite时,应该即时关闭连接;打开连接后,尽量减少非常费时的操作。

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

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

最后通过FMDatabaseQueue解决了这个问题,本文总结一下:

FMDatabase 不能多线程使用一个实例

多线程访问数据库,不能使用同一个FMDatabase 的实例。否则会发生异常。如果线程使用单独的FMDatabase 实例是允许的,但是同样有可能发生database is locked的问题。这是由于多线程对sqlite的竞争引起的

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

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

创建一个DBHelper 类

使用FMDatabaseQueue之后,管理db

原本使用FMDatabase类,需要手工调用db的open和close方法

但是用FMDatabaseQueue,不需要调用open,因为查看代码发现,Queue已经open了。至于要不要close,我也不确定,因为官方的sample code没有调用close。实际应用中,我也没有调用,好像没有问题。

所以,使用Queue,是不需要自己打开和关闭db的。但是如果使用了FMResultSet,rs倒是需要关闭,否则会报warning:

if ([db hasOpenResultSets]) {

NSLog(@"Warning: there is at least one open result set around after performing [FMDatabaseQueue inDatabase:]");

为了不看到warning,我都在block里调用了[rs close]

刷新数据库文件路径

具体到我们的应用,还有一个特殊问题需要考虑。因为我们的APP可以切换账户,而账户的db文件是独立的。所以当用户重新登录的时候,需要刷新一下Helper的queue

如果不这么做,由于Helper是单例,那么切换账户以后,用户B访问的还是用户A的数据库。刷新的调用,一般放在登录之后,进入主页面之前就可以了

IOS 使用FMDB多线程访问数据库 及databaseislocked的问题的更多相关文章

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

    每日更新关注:http://weibo.com/hanjunqiang  新浪微博 今天终于解决了多线程同时访问数据库时,报数据库锁定的问题,错误信息是: Unknown error finalizi ...

  2. iOS中 FMDB第三方SQLite数据库 UI_20

    1.什么是FMDB? FMDB是iOS平台下SQLite数据库,只不过它是OC方式封装了C语言的SQLite语句,使用起来更加面向对象 2.FMDB的优点:1.使用起来更加面向对象; 2.对比苹果自带 ...

  3. iOS 使用FMDB SQLCipher给数据库加密

    关于SQLite,SQLCipher和FMDB SQLite是一个轻量的.跨平台的.开源的数据库引擎,它的在读写效率.消耗总量.延迟时间和整体简单性上具有的优越性,使其成为移动平台数据库的最佳解决方案 ...

  4. IOS使用FMDB封装的数据库增删改查操作

    // //  DBHelper.h //  LessonStoryBoard // //  Created by 袁冬冬 on 15/10/29. //  Copyright (c) 2015年 袁冬 ...

  5. (原创)android Sqlite多线程访问异常解决方案

    在开发Android的程序的时候sqlite数据库是经常用到的:在多线程访问数据库的时候会出现这样的异常:java.lang.IllegalStateException: Cannot perform ...

  6. iOS——使用FMDB进行数据库操作(转载)

    iOS 使用FMDB进行数据库操作 https://github.com/ccgus/fmdb [摘要]本文介绍iOS 使用FMDB进行数据库操作,并提供详细的示例代码供参考. FMDB 使用方法 A ...

  7. [R语言]R语言使用多线程对数据库进行大批量访问时出现无法连接问题

    问题描述: 在R中使用多线程对数据库进行写入,在服务器端运行脚本(linux环境),总是在第6-7万个任务线程时,出现无法连接到数据库的问题.任务中断,错误信息为task 6xxxx failed,C ...

  8. ios开发FMDB导入SQLCipher加密数据库

    转:http://www.2cto.com/kf/201407/315727.html [iOS]FMDB/SQLCipher数据库加解密,迁移

  9. iOS Core data多线程并发访问的问题

    大家都知道Core data本身并不是一个并发安全的架构:不过针对多线程访问带来的问题,Apple给出了很多指导:同时很多第三方的开发者也贡献了很多解决方法.不过最近碰到的一个问题很奇怪,觉得有一定的 ...

随机推荐

  1. easylui datagrid 动态生成列

    function load(sdate) { $.getJSON("workorder/statistics.do", { sdate : sdate+'-01' }, funct ...

  2. Hibernate的关联映射——单向1-N关联

    Hibernate的关联映射--单向1-N关联 单向1-N关联的持久化类里需要使用集合属性.因为1的一端需要访问N的一端,而N的一端将以集合(Set)形式表现.从这个意义上来看,1-N(实际上还包括N ...

  3. Java中byte与16进制字符串的互相转换

    * Convert byte[] to hex string.这里我们可以将byte转换成int,然后利用Integer.toHexString(int)来转换成16进制字符串. * @param s ...

  4. centos7 docker mysql56

    yum -y install docker docker pull centos docker run --name=mysqltmp -i -t centos /bin/bash yum -y in ...

  5. 用Python编写的第一个回测程序

    用Python编写的第一个回测程序 2016-08-06 def savfig(figureObj, fn_prefix1='backtest8', fn_prefix2='_1_'): import ...

  6. python的ujson与simplejson

    一.使用了simplejson import simplejson as json 二.使用ujson import ujson as json 参考链接:下载win下的:ujson

  7. (七)HTTP协议

    HTTP协议报文基本格式 HTTP协议报文基本格式       HTTP协议(Hypertext Transfer Protocol――超文本传输协议),浏览器端(客户端)向WEB服务器端访问页面的过 ...

  8. applicationContext.xml简单笔记

    applicationContext.xml简单笔记 <?xml version="1.0" encoding="UTF-8"?> <bean ...

  9. 【Java基础】分支结构(1)

    java 分支结构 if , if else , if elseif if /** 文件路径:G:\JavaByHands\if-else\ 文件名称:IfElseT.java 编写时间:2016/6 ...

  10. java complier compliance level问题引发的思考

    http://blog.csdn.net/shan9liang/article/details/17266519 ******************************************* ...