SQLite数据库多线程操作:

在上面一节中已经讲过FMDB的用法了,接下来讲讲sqlite在都线程中的用法。如果应用中使用了多线程操作数据库,那么就需要使用FMDatabaseQueue来保证线程安全了。 应用中不可在多个线程中共同使用一个FMDatabase对象操作数据库,这样会引起数据库数据混乱。 为了多线程操作数据库安全,多线程FMDatabaseQueue 这个类在多个线程来执行查询和更新时会使用这个类。避免同时访问同一个数据FMDatabaseQueue。首先用一个数据库文件地址来初使化FMDatabaseQueue,然后就可以将一个闭包(block)传入inDatabase方法中。 在闭包中操作数据库,而不直接参与FMDatabase的管理。

注意点:

1.FMDatabaseQueue是一个串行队列,它不支持串行任务嵌套执行

[(FMDatabaseQueue的单例) inDatabase:^(FMDatabase *db) {FMResultSet *result = [db executeQuery:[NSStringstringWithFormat:@"select * from BookClassify order by classifyID desc"]];while ([result next]) {//处理result}
[(FMDatabaseQueue的单例) inDatabase:^(FMDatabase *db) {
//有问题了}];}];
可以用db再次进行sql操作、不必再inDatabase
2.FMDatabaseQueue不是在次线程中操作、若要次线程操作在外面要包一个dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{});

FMDatabaseQueue保证线程安全基本用法

——主要就是在创建数据库的时候,默认已经打开数据库

——随后的很多操作,因为需要在数据库中操作,所以需要利用队列的inDataBase方法调出数据库,在block中执行操作代码。

#import "ViewController.h"
#import "FMDB.h"@interface ViewController ()
@property(nonatomic,strong) FMDatabaseQueue *queue;
- (IBAction)insert:(id)sender;
- (IBAction)delete:(id)sender;
- (IBAction)update:(id)sender;
- (IBAction)select:(id)sender;
@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];NSString *filePath=[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"fmdb.sqlite"];//创建数据库,并加入到队列中,此时已经默认打开了数据库,无须手动打开,只需要从队列中取出数据库即可self.queue=[FMDatabaseQueue databaseQueueWithPath:filePath];//取出数据库,这里的db就是数据库,在数据库中创建表[self.queue inDatabase:^(FMDatabase *db) {//创建表BOOL createTableResult=[db executeUpdate:@"CREATE TABLE IF NOT EXISTS t_student (id integer PRIMARY KEY AUTOINCREMENT,name text,age integer)"];if (createTableResult) {NSLog(@"创建表成功");}else{NSLog(@"创建表失败");}}];
}- (IBAction)insert:(id)sender {[self.queue inDatabase:^(FMDatabase *db) {for (int index=0; index<50; index++) {NSString *s_name=[NSString stringWithFormat:@"Andy%d",arc4random()%100];NSNumber *s_age=@(arc4random()%100);[db executeUpdate:@"INSERT INTO t_student(name,age) VALUES(?,?)",s_name,s_age];}}];
}- (IBAction)delete:(id)sender {[self.queue inDatabase:^(FMDatabase *db) {[db executeUpdate:@"DELETE FROM t_student WHERE id=?",@1];}];
}- (IBAction)update:(id)sender {[self.queue inDatabase:^(FMDatabase *db) {[db executeUpdate:@"UPDATE t_student SET name='Jack' WHERE id=?",@2];}];
}- (IBAction)select:(id)sender {[self.queue inDatabase:^(FMDatabase *db) {//获取结果集,返回参数就是查询结果FMResultSet *rs=[db executeQuery:@"SELECT * FROM t_student WHERE age>?",@50];while ([rs next]) {int ID=[rs intForColumn:@"id"];NSString *NAME=[rs stringForColumn:@"name"];int AGE=[rs intForColumn:@"age"];NSLog(@"%d %@ %d",ID,NAME,AGE);}}];
}

如果要保证多个操作同时成功或者同时失败,用事务,即把多个操作放在同一个事务中。

——FMDB中,拿到数据库直接操作事务,如下:

- (IBAction)update:(id)sender {[self.queue inDatabase:^(FMDatabase *db) {[db beginTransaction];//开始事务[db executeUpdate:@"UPDATE t_student SET name='Jack' WHERE id=?",@2];[db executeUpdate:@"UPDATE t_student SET name='Tomy' WHERE id=?",@3];//发现情况不对时,主动回滚用下面语句。否则是根据commit结果,如成功就成功,如不成功才回滚[db rollback];//主动回滚[db executeUpdate:@"UPDATE t_student SET name='Eric' WHERE id=?",@4];[db commit];//提交事务}];
}

上面因为用的是FMDB封装好的,其实原生的代码是这样的:

[db executeUpdate:@"BEGIN TRANSACTION"];
[db executeUpdate:@"ROLLBACK TRANSACTION"];
[db executeUpdate:@"COMMIT TRANSACTION"];

——FMDB中,也可以直接利用队列进行事务操作,队列中的打开、关闭、回滚事务等都已经被封装好了。

- (IBAction)update:(id)sender {[self.queue inDatabase:^(FMDatabase *db) {[self.queue inTransaction:^(FMDatabase *db, BOOL *rollback) {[db executeUpdate:@"UPDATE t_student SET name='Jack' WHERE id=?",@2];[db executeUpdate:@"UPDATE t_student SET name='Tomy' WHERE id=?",@3];//发现情况不对时,主动回滚用下面语句。*rollback=YES;[db executeUpdate:@"UPDATE t_student SET name='Eric' WHERE id=?",@4];}];
}

FMDatabaseQueue 数据库多线程操作、事务处理相关推荐

  1. 多线程操作数据库时为了防止数据的增删改的混乱该在数据库层还是程序层面上进行同步?

    多线程操作数据库时为了防止数据的增删改的混乱该在数据库层还是程序层面上进行同步? [问题点数:60分,结帖人jiao_zg] 不显示删除回复 显示所有回复 显示星级回复 显示得分回复 只显示楼主 收藏 ...

  2. python多线程读取数据库数据_python多线程操作MySQL数据库pymysql

    python多线程操作MySQL数据库pymysql 项目中使用多线程操作数据库提示错误:pymysql.err.InterfaceError: (0, "),原因是pymysql的exec ...

  3. python多线程读取数据库数据_Python基于多线程操作数据库相关知识点详解

    Python基于多线程操作数据库相关问题分析 本文实例分析了Python多线程操作数据库相关问题.分享给大家供大家参考,具体如下: python多线程并发操作数据库,会存在链接数据库超时.数据库连接丢 ...

  4. SQLite数据库操作+事务处理

    SQLite数据库操作 SQLite数据库介绍 Android系统中集成的轻量级的数据库 特点: 轻量级 是以单个文件的形式进行存取 跨平台 支持多个操作系统 零配置 无需安装, 直接使用 嵌入式 内 ...

  5. Core Data 多线程操作实战篇

    最近在解决百度音乐iPhone客户端偶现数据库操作crash的问题,顺手整理了下CoreData的多线程原则,以及实际开发时应该如何遵守这些原则. Core Data多线程操作的基本原则 不允许跨线程 ...

  6. C#多线程操作界面控件的解决方案

    C#中利用委托实现多线程跨线程操作 - 张小鱼 2010-10-22 08:38 在使用VS2005的时候,如果你从非创建这个控件的线程中访问这个控件或者操作这个控件的话就会抛出这个异常.这是微软为了 ...

  7. 更高效地提高redis client多线程操作的并发吞吐设计

    Redis是一个非常高效的基于内存的NOSQL数据库,它提供非常高效的数据读写效能.在实际应用中往往是带宽和CLIENT库读写损耗过高导致无法更好地发挥出Redis更出色的能力.下面结合一些redis ...

  8. python的多线程适合计算密集操作_Python 多线程操作学习

    Python 多线程操作 什么是线程: 线程(Thread)也叫轻量级进程,是操作系统能够进行运算调度的最小单位,它被包涵在进程之中,是进程中的实际运作单位.线程自己不拥有系统资源,只拥有一点儿在运行 ...

  9. 高效Redis Client多线程操作的并发吞吐设计

    Redis是一个非常高效的基于内存的NOSQL数据库,它提供非常高效的数据读写效能.在实际应用中往往是带宽和CLIENT库读写损耗过高导致无法更好地发挥出Redis更出色的能力.下面结合一些redis ...

最新文章

  1. sql server 2008建域时提示admin密码不符合要求解决方法
  2. 机器学习-类别不平衡问题
  3. [转]ExtJS Grid 分页时保持选中的简单实现方法
  4. 应用adb发布apk到android avd模拟器
  5. pysparkpython版本_pyspark修改python版本
  6. Spark _23 _读取parquet文件创建DataFrame(二)
  7. 现代制造工程课堂笔记03:第二部分(含易考点与必考点)
  8. C#趣味程序---水仙花数
  9. 一个月 200 题,命中 80%,拿下 BAT,我独特的高效刷题法
  10. jQuery 中bind(),live(),delegate(),on() 区别
  11. window.location.href如何多次请求_测试同学必会系列之如何进行幂等性的测试
  12. 区块链技术与微服务架构之间有什么关系?
  13. soapUI简介、安装使用教程、接口(性能)测试
  14. 10个我经常逛的“小网站”,嘿嘿嘿
  15. 工作压力不容忽视——网易公司宣布首席执行官孙德棣18日辞世
  16. 山东大学软件学院项目实训-创新实训-网络安全靶场实验平台(十六)
  17. ThinkPHP 关闭调试模式
  18. php.bak是什么,bak文件是什么
  19. intellij IDEA修改快捷键以及添加菜单快捷键
  20. Java数据类型在内存中储存方式

热门文章

  1. Science:科学家亲眼看到细菌产生耐药性的全过程(视频)
  2. php mysql or_mysql条件查询and or使用方法及优先级实例分析
  3. python使用matplotlib可视化包含倒影的柱状图(bar plot with shadow)、配置rcParams坐标轴正确显示负号(-)
  4. R语言可视化图像中最常用的点样式(pch、plot characters)列表、ggpubr::show_point_shapes可视化最常用的点样式(pch)
  5. R语言使用tidyquant包的tq_transmute函数计算持有某只股票的天、月、周收益率、ggplot2使用条形图(bar plot)可视化股票年收益率数据使用不同的色彩表征正收益率和负收益率
  6. Python把matplotlib绘制的水平条形图(horizontal bar)转化为竖直的柱状图(vertical bar)实战
  7. sklearn可视化不同数据划分方法的差异:KFold, ShuffleSplit,StratifiedKFold, GroupKFold, StratifiedShuffleSplit.......
  8. PCA(principal component analysis)主成分分析降维和KPCA(kernel principal component analysis​​​​​​​)核
  9. java异常对象引用变量_Java面向对象编程-异常处理
  10. 02 数据类型 (向量 数据框 矩阵和列表