fmdb中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. if (whoopsSomethingWrongHappened) {
  7. *rollback = YES; return;
  8. }
  9. // etc…
  10. [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:4]];
  11. }];

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

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

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

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

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

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

fmdb中databasequeue的使用,避免死锁,布布扣,bubuko.com

时间: 2024-08-08 22:06:58

fmdb中databasequeue的使用,避免死锁的相关文章

java中同步嵌套引起的死锁事例代码

/* 目的:自己写一个由于同步嵌套引起的死锁! 思路:多个线程在执行时,某一时刻,0-Thread绑定了LockA锁,1-Thread绑定了LockB锁! 当0-Thread要去绑定LockB锁时 和 1-Thread要去绑定LockA锁时都不能绑定,此时两个线程不能继续进行! */ class Ticket implements Runnable{ public boolean flag; Ticket(boolean flag){ this.flag = flag; } Ticket(){

FMDB中的数据处理

1 [self.db executeUpdate:@"create table test (a text, b text, c integer, d double, e double)"]; 我们创建一个表格text,可以很清楚的看到其字段对应的数据类型: 数据类型: TEXT:字符串类型.INTEGER:整型.REAL:浮点型(double.float).BLOB:二进制数据 关于 ‘?’:FMDB中 ‘?’ 表示对象占位符,不能用来占位基本数据类型!! 那么我们插入数据的时候,可以

Java程序中解决数据库超时与死锁

Java程序中解决数据库超时与死锁 2011-06-07 11:09 佚名 帮考网 字号:T | T Java程序中解决数据库超时与死锁,每个使用关系型数据库的程序都可能遇到数据死锁或不可用的情况,而这些情况需要在代码中编程来解决.本文主要介绍与数据库事务死锁等情况相关的重试逻辑概念. AD: Java程序中解决数据库超时与死锁,每个使用关系型数据库的程序都可能遇到数据死锁或不可用的情况,而这些情况需要在代码中编程来解决;本文主要介绍与数据库事务死锁等情况相关的重试逻辑概念,此外,还会探讨如何避

SQL优化中的重要概念:死锁

原文:SQL优化中的重要概念:死锁 上面几篇文章讲到 事务.锁定.阻塞,最后还有一种比较极端的情况,就是死锁,这也是锁定.阻塞的一种情况. 死锁是当两个事务分别锁定了资源,而又继续请求对方已获取的资源,那么就会产生死锁. 发生死锁的原因: A.会话以不同的顺序访问表. B.会话长时间运行事务,在一个事务中更新了很多表或行,这样增加了冲突的可能. C.会话1申请了一些行锁,会话2申请了一些行锁,之后决定将其升级为表锁. 如果这些行在相同的数据页面中,并且两个会话同时在相同的页面上升级锁粒度,就会产

FMDB中常用SQL使用

大家工作中,最常用到的无非是 增.删.查.改... 在SQL中对应的语句为:INSERT DELETE SELECT UPDATE 首先,你可以使用一款叫做"sqlite database browser"的工具来可视化的管理数据库. 然后把数据库文件加入到Resource目录下,然后通过以下代码来安装数据库,也就是拷贝到doc目录下: [cpp] view plain copy //install file to doc dir - (BOOL)installFileOfName:(

IOS:FMDB使用databaseQueue实现数据库操作线程安全

sqlite数据库是ios开发中经常使用到的数据持久化方案,因为项目需求的不同,对数据库操作的要求也不同. 由于最近使用sqlite时,有一些地方需要频繁的更新,这时在多线程操作时,其他线程访问数据库会造成程序崩溃,因为之前的框架里设计的数据库管理工具类采用的是单例模式,这样在多线程操作同一个数据库时很容易引起冲突,导致程序崩溃,所以开始寻找多线程下线程安全的办法. 其实FMDB本身已经对多线程做了考虑,FMDatabaseQueue就是为了解决数据库操作线程安全的,只是由于之前框架集成的单例操

你的眼睛背叛你的心:解决 .NET Core 中 GetHostAddressesAsync 引起的 EnyimMemcached 死锁问题

在我们将站点从 ASP.NET + Windows 迁移至 ASP.NET Core + Linux 的过程中,目前遇到的最大障碍就是 —— 没有可用的支持 .NET Core 的 memcached 客户端. 我们一直用的是 EnyimMemcached ,在没有其它选择的情况下,我们自己尝试着将 EnyimMemcached 迁移至 .NET Core...基于 .NET Core 修改好了代码,在开发环境下测试通过,在 Linux 服务器上自己访问很正常(没有并发访问量),但是只要接入一定

.NET Core中遇到奇怪的线程死锁问题:内存与线程数不停地增长

一个 asp.net core 站点,之前运行在Linux 服务器上,运行一段时间后有时站点会挂掉,在日志中记录很多“EMFILE too many open files”的错误: Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException: Error -24 EMFILE too many open files 后来将这个 asp.net 站点部署到 Windows 服务器的 IIS 上.运行一段时间后,发现其中一台

java中多线程的线程同步死锁问题

/* *定义一个多线程 */ package com.thread; public class TicketThread2 implements Runnable { //定义1000张票 public static int ticket = 100; Object obj = new Object(); // public boolean flag = false; // public boolean exit = false; @Override public void run() { //