今天比较闲看到大家在群里讨论关于数据库操作的问题,其中谈到了“事务”这个词,坦白讲虽然作为计算机专业的学生,在上学的时候确实知道存储过程、触发器、事务等等这些名词的概念,但是由于毕业后从事的不是服务器方面的工作,对数据库方面的知识一直停留在理论阶段,在iOS中有两种比较常用的数据库,一种是sqlite,另外一种是coreData,这二者的优缺点在这里不再赘述,如有感兴趣的同学可以查阅相关资料

  令人兴奋的是,当谈到“事务”时,我想到了sqlite本身是支持事务操作的,FMDB作为sqlite的上层封装也对事务进行了支持,那么说了这么多给不了解“事务”这个词的同学解释一下吧:通常一次 sqlite3_exec 就是一次事务,假如你要对数据库中的Stutent表插入新数据,那么该事务的具体过程是:开始新事物->插入数据->提交事务,那么当我们要往该表内插入500条数据,如果按常规操作处理就要执行500次“开始新事物->插入数据->提交事务”的过程。

  好吧,今天的重点来了,举个例子:假如北京的一家A工厂接了上海一家B公司的500件产品的订单,思考一下:A工厂是生产完一件立即就送到B公司还是将500件产品全部生产完成后再送往B公司?答案肯定是后者,因为前者浪费了大量的时间、人力物力花费在往返于北京和上海之间。同样这个道理也能用在我们的数据库操作上,下面是我自己对使用事务和不使用事务的两种测试:

测试代码:

下面代码中总共调用了三次插入数据的方法,由于第一次调用过程中包含数据库和表的创建等一系列过程,因此第二三次调用插入方法计算出的时间才是准确的。(数据库采用FMDB)

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[[TestDataBase sharedInstanceDB] insertData:0 useTransaction:NO];
NSDate *date1 = [NSDate date];
[[TestDataBase sharedInstanceDB] insertData:500 useTransaction:NO];
NSDate *date2 = [NSDate date];
NSTimeInterval a = [date2 timeIntervalSince1970] - [date1 timeIntervalSince1970];
NSLog(@"不使用事务插入500条数据用时%.3f秒",a);
[[TestDataBase sharedInstanceDB] insertData:1000 useTransaction:YES];
NSDate *date3 = [NSDate date];
NSTimeInterval b = [date3 timeIntervalSince1970] - [date2 timeIntervalSince1970];
NSLog(@"使用事务插入500条数据用时%.3f秒",b);
}

下面是具体的插入实现方法,

useTransaction为真代表使用事务处理,反之不使用

- (void)insertData:(int)fromIndex useTransaction:(BOOL)useTransaction
{
[_dataBase open];
if (useTransaction) {
[_dataBase beginTransaction];
BOOL isRollBack = NO;
@try {
for (int i = fromIndex; i<500+fromIndex; i++) {
NSString *nId = [NSString stringWithFormat:@"%d",i];
NSString *strName = [[NSString alloc] initWithFormat:@"student_%d",i];
NSString *sql = @"INSERT INTO Student (id,student_name) VALUES (?,?)";
BOOL a = [_dataBase executeUpdate:sql,nId,strName];
if (!a) {
NSLog(@"插入失败1");
}
}
}
@catch (NSException *exception) {
isRollBack = YES;
[_dataBase rollback];
}
@finally {
if (!isRollBack) {
[_dataBase commit];
}
}
}else{
for (int i = fromIndex; i<500+fromIndex; i++) {
NSString *nId = [NSString stringWithFormat:@"%d",i];
NSString *strName = [[NSString alloc] initWithFormat:@"student_%d",i];
NSString *sql = @"INSERT INTO Student (id,student_name) VALUES (?,?)";
BOOL a = [_dataBase executeUpdate:sql,nId,strName];
if (!a) {
NSLog(@"插入失败2");
}
}
}
[_dataBase close];
}

最后将两种方式的耗时进行对比(此结果在模拟器中运行)

从上面这些真实的数据来看,你就应该知道当你批量更新数据库的时候应该利用事务处理!

总结:使用事务处理就是将所有任务执行完成以后将结果一次性提交到数据库,如果此过程出现异常则会执行回滚操作,这样节省了大量的重复提交环节所浪费的时间。

原文出自:http://www.cnblogs.com/zzltjnh/p/FMDB_Transaction.html

iOS中使用FMDB事务批量更新数据库的更多相关文章

  1. 使用FMDB事务批量更新数据库

    今天比较闲看到大家在群里讨论关于数据库操作的问题,其中谈到了“事务”这个词,坦白讲虽然作为计算机专业的学生,在上学的时候确实知道存储过程.触发器.事务等等这些名词的概念,但是由于毕业后从事的不是服务器 ...

  2. iOS中 用FMDB封装一个SQLite数据库

    建立一个单例: DataBaseHandle.h #import <Foundation/Foundation.h> @class PersonModel; @class FMDataba ...

  3. SQL批量更新数据库中所有用户数据表中字段类型为tinyint为int

    --SQL批量更新数据库中所有用户数据表中字段类型为tinyint为int --关键说明:--1.从系统表syscolumns中的查询所有xtype='48'的记录得到类型为[tinyint]的字段- ...

  4. SqlDataAdapter 批量更新数据库表

    在数据库中批量插入数据许多人都已经了解了,就是使用.net 中的SqlBulkCopy对象(MSDN详解).我们在做评教系统的时候使用过这个对象,它能将数据表批量导入到数据库中,效率比单条插入数据效率 ...

  5. 在IOS中使用DES算法对Sqlite数据库进行内容加密存储并读取解密

    在IOS中使用DES算法对Sqlite 数据库进行内容加密存储并读取解密 涉及知识点: 1.DES加密算法: 2.OC对Sqlite数据库的读写: 3.IOS APP文件存储的两种方式及读取方式. 以 ...

  6. Mybatis批量更新数据库与批量插入数据库(以oracle为例)

    一.批量更新 1.普通写法(一条记录update一次,性能比较差,容易造成阻塞.不建议使用) <update id="updateBatch" parameterType=& ...

  7. 在ios中使用FMDB

    SQLite (http://www.sqlite.org/docs.html) 是一个轻量级的关系数据库.iOS SDK很早就支持了SQLite,在使用时,只需要加入 libsqlite3.dyli ...

  8. sql server中的锁 事务锁 更新锁 保持锁 共享锁 你知道吗?

    锁定数据库的一个表 SELECT * FROM table WITH (HOLDLOCK) 注意: 锁定数据库的一个表的区别 SELECT * FROM table WITH (HOLDLOCK) 其 ...

  9. Java中如何实现j并发更新数据库同一条数据

    分情况来说:普通单应用并发.多应用或多台服务器并发 情况一:普通单应用并发 使用关键字synchronized就可实现. 情况二:多应用或多台服务器并发 因多个应用之间并非同一个jvm(应用)内,因此 ...

随机推荐

  1. bootstrap3-typeahead 自动补全

    很酷的一个自动补全插件 http://twitter.github.io/typeahead.js 在bootstrap中使用typeahead插件,完成自动补全 相关的文档:https://gith ...

  2. 如何在Dynamics CRM 2011 的窗体表单上加载报表

    1.代码 function onloadReport() { if (crmForm.FormType != 1 && crmForm.FormType != 5) { $(" ...

  3. eclipse 怎么新建工作空间workspace

    打开eclipse 点击文件“File”菜单切换工作空间“Switch Workspace”>其它“Other” 点击“Browser”选择新的工作空间目录. 选择新的工作空间目录,点击确定. ...

  4. Genymotion出现Unable to load VirtualBox engine问题--100%解决

    首先强调一个事情,作为程序员,一定要养成一个习惯:安装软件时尤其像VirtualBox这类,首先设置其"兼容模式"以及"特权等级" . 环境:win7 64bi ...

  5. (转帖)BootStrap入门教程 (二)

    上讲回顾:Bootstrap的手脚架(Scaffolding)提供了固定(fixed)和流式(fluid)两种布局,它同时建立了一个宽达940px和12列的格网系统. 基于手脚架(Scaffoldin ...

  6. 【Oracle学习笔记-4】内连接和外连接的区别

    参考链接(非常棒) 摘要 下面主要以两个例子进行说明: 例子1: 表A结构如下: select * from A | 表B结构如下: select * from B 两个表要做连接,就必须有个连接字段 ...

  7. Spring实战3:装配bean的进阶知识

    主要内容: Environments and profiles Conditional bean declaration 处理自动装配的歧义 bean的作用域 The Spring Expressio ...

  8. C语言每日一题之No.12

    文件操作知识:如何将一个文件的内容读取到另一个文件里? fread函数和fwrite函数   1.函数功能   用来读写一个数据块. 2.一般调用形式   fread(buffer,count,siz ...

  9. 从SVN导出指定版本号之间修改的文件

    当一个网站项目进入运营维护阶段以后,不会再频繁地更新全部源文件到服务器,这个时间的修改大多是局部的,因此更新文件只需更新修改过的文件,其他 没有修改过的文件就没有必要上载到服务器.但一个稍微上规模的网 ...

  10. 原生JavaScript实现的addclass,removeclass,hasclass,toggleclass,getbyclass

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...