原理:文件数据库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. noi 1944 吃糖果

    题目链接:http://noi.openjudge.cn/ch0206/1944/ 根据第一天吃的个数递推,发现这个递推关系很像斐波那契数列. http://paste.ubuntu.com/2340 ...

  2. 自定义Dialog

    功能:从底部弹出的对话框,加入动画 步骤:1 定义dialog布局文件 2 设置标题,透明度style.xml,选择器selector.xml ,圆角shape.xml 等样式文件 3 设置显示位置, ...

  3. Determining Current Block and Current Item in Oracle Forms

    SYSTEM.CURSOR_BLOCK Determining current block in Oracle Forms Using SYSTEM.CURSOR_BLOCK system varia ...

  4. 简单的SpringMVC的测试项目----跟struts2对比着学习

    一,搭建SpringMVC项目 1,主配置文件-----地基 because,不像struts2是个独立的框架,可以脱离Spring单独使用.需要先添加Spring支持,是Spring框架组成的一部分 ...

  5. Js获取下拉框选定项的值和文本

    Js获取下拉框的值和文本网上提供了2种方法:但有些人很不负责任,他们根本没考虑到浏览器之间的差异导致的错误,导致很多新手琢磨了半天找不出错误! 下面我总结下Firefox和IE下获取下拉框选定项的值和 ...

  6. 解决方法 test: database removal failed: ERROR: database "test" is being accessed by other users

    select * from pg_stat_activity where datname='test'; 找出哪个进程用了这个数据库,然后删除这个进程(pid) kill -9 47182 然后再删除 ...

  7. fsimage 和 edits log

    standby NN每隔一段时间(由参数dfs.ha.tail-edits.period决定,默认是60s)去检查Journal node上新的Edits log文件. standby NN每隔一段时 ...

  8. openssl evp 哈希算法(md5,sha1,sha256)

    1. 简述 openssl提供了丰富密码学工具,一些常用的哈希算法 比如md5,sha 可以直接用提供的md5.h ,sha.h 接口使用: 为了方便开发者使用,openssl 又提供了一个EVP, ...

  9. CentOS PPTP配置FreeRADIUS+DaloRADIUS实现高级用户控制+流量控制

    前提条件 阅读本文前,您需要搭建好PPTP,如果仍未搭建,可以参考:http://www.xj123.info/2301.html 如果您需要配置DaloRADIUS,那么您还需要安装LAMP,可以参 ...

  10. jQuery1.9为动态添加元素绑定事件以及获取和操作checkbox的选择属性

    1.jQuery为动态添加的元素绑定事件:在1.7之后,添加了live()方法,1.9后又被移除,1.9中可用on()方法: $(function() { $('.btn').on('click',  ...