fmdb中databasequeue的使用,避免死锁

简介: 在ios开发中,大家很可能会用到这样一个数据库封装:fmdb. 该封装相比coredata来说有他自己的优势:接口清晰,设计简单,符合规范,多线程情况下使用databasequeue来进行操作也很方便,还可以在其基础上再进行一些封装来方便项目的使用。

在ios开发中,大家很可能会用到这样一个数据库封装:fmdb.

该封装相比coredata来说有他自己的优势:接口清晰,设计简单,符合规范,多线程情况下使用databasequeue来进行操作也很方便,还可以在其基础上再进行一些封装来方便项目的使用。


正是因为fmdb的简单性,所以很容易被误用。在我们的项目开发中就遇到了一例(我们项目中的代码进行了封装,我这里将其还原,写示例来作说明):


 
  1. [queue inTransaction:^(FMDatabase *db, BOOL *rollback) {    
  2.             [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]];    
  3.             [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]];    
  4.             [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:3]];  
  5.     [
    queue
    inDatabase:^(FMDatabase *db) {
            // do work B
        }];

  6.  
  7.             if (whoopsSomethingWrongHappened) {    
  8.                     *rollback = YES; return;    
  9.             }   
  10.             // etc…    
  11.             [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:4]];    
  12.     }];  

注意第6行往下,是不是混入了什么奇怪的东西?

从这里看起来问题非常明显了,但实际项目中接口被进行了一些封装,所以很难一眼看出问题,这里的问题是这样的:

在queue的事务内部又嵌套使用了该queue去执行任务b,而作为一个串行化的队列来说必须要等该事务整个执行完毕才能执行任务b;此时任务b无法走下去,该事务也就无法执行完毕,导致了死锁。

用一个比喻来说这个问题:一个人出门把门锁上了,然后把钥匙从门缝又塞回到家里,这样他就无法再进入家门了。

这个误用其实很低级,而且从原理上讲任何串行队列里面串行任务嵌套执行都有问题。


另外,fmdb的官方文档也多次提醒避免嵌套使用,请大家写代码的时候一定要注意~





目录
相关文章
|
SQL 安全 API
Swift(FMDB的简单使用)
Swift(FMDB的简单使用)
939 0
Swift(FMDB的简单使用)
|
SQL 存储 关系型数据库
MySQL数据库——锁-表级锁(表锁、元数据锁、意向锁)
MySQL数据库——锁-表级锁(表锁、元数据锁、意向锁)
1017 0
|
NoSQL 关系型数据库 MySQL
Centos7 安装Docker,常用命令,设置国内阿里云镜像,并且在docker中安装MySQL、Redis
Centos7 安装Docker,常用命令,设置国内阿里云镜像,并且在docker中安装MySQL、Redis
3468 0
Centos7 安装Docker,常用命令,设置国内阿里云镜像,并且在docker中安装MySQL、Redis
|
应用服务中间件 nginx
|
安全 Linux 网络安全
生存还是毁灭?一文读懂挖矿木马的战略战术
比特币等虚拟货币在2019年迎来了久违的大幅上涨,从最低3000美元上涨至7月份的14000美元,涨幅达300%,巨大的金钱诱惑使得更多的黑产团伙加入了恶意挖矿的行列。阿里云安全团队通过对云上僵尸网络家族的监控,发现恶意挖矿已成为黑产团伙主要的牟利方式。
11187 0
|
Web App开发 移动开发 前端开发
如何用 Electron + WebRTC 开发一个跨平台的视频会议应用
在搭建在线教育、医疗、视频会议等场景时,很多中小型公司常常面临 PC 客户端和 Web 端二选一的抉择。Electron 技术的出现解决了这一难题,只需前端开发就能完成一个跨平台的 PC 端应用。本文主要介绍使用 Electron + WebRTC 搭建跨平台的视频会议应用的技术方案。
如何用 Electron + WebRTC 开发一个跨平台的视频会议应用
|
编解码 Python
python 如何绘制全球风场(以2020年月均数据为例)
python 如何绘制全球风场(以2020年月均数据为例)
python 如何绘制全球风场(以2020年月均数据为例)
|
安全 应用服务中间件 API
JWT和OAuth2.0
JWT是一种认证协议,提供了一种用于发布接入令牌(Access Token),并对发布的签名接入令牌进行验证的方法。SSO私钥加密token。应用端公钥解密token。 OAuth2.0是一种授权框架,提供了一套详细的授权机制(指导)。用户或应用可以通过公开的或私有的设置,授权第三方应用访问特定资源。
688 0
JWT和OAuth2.0
|
机器学习/深度学习 数据可视化 算法
基于深度学习的瓶子检测软件(UI界面+YOLOv5+训练数据集)
基于深度学习的瓶子检测软件(UI界面+YOLOv5+训练数据集)
1053 0
|
安全 Java 大数据
一文搞懂什么是“注解”
一文搞懂什么是“注解”
1062 0
一文搞懂什么是“注解”