举个例子:假如北京的一家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);}
- (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];}
最后将两种方式的耗时进行对比(此结果在模拟器中运行)
从上面这些真实的数据来看,你就应该知道当你批量更新数据库的时候应该利用事务处理!
总结:使用事务处理就是将所有任务执行完成以后将结果一次性提交到数据库,如果此过程出现异常则会执行回滚操作,这样节省了大量的重复提交环节所浪费的时间