轉自: http://www.cnblogs.com/zzltjnh/p/FMDB_Transaction.html
當談到“事務”時,我想到了sqlite本身是支援事務操作的,FMDB作為sqlite的上層封裝也對事務進行了支援,那麼說了這麼多給不了解“事務”這個詞的同學解釋一下吧:通常一次 sqlite3_exec 就是一次事務,假如你要對資料庫中的Stutent表插入新資料,那麼該事務的具體過程是:開始新事物->插入資料->送出事務,那麼當我們要往該表内插入500條資料,如果按正常操作處理就要執行500次“開始新事物->插入資料->送出事務”的過程。
好吧,今天的重點來了,舉個例子:假如北京的一家A工廠接了上海一家B公司的500件産品的訂單,思考一下:A工廠是生産完一件立即就送到B公司還是将500件産品全部生産完成後再送往B公司?答案肯定是後者,因為前者浪費了大量的時間、人力物力花費在往返于北京和上海之間。同樣這個道理也能用在我們的資料庫操作上,下面是我自己對使用事務和不使用事務的兩種測試:
測試代碼:
下面代碼中總共調用了三次插入資料的方法,由于第一次調用過程中包含資料庫和表的建立等一系列過程,是以第二三次調用插入方法計算出的時間才是準确的。(資料庫采用FMDB)
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLlR2bjlHcvN2LcNXZnFWbp9CXt92YuM3ZvxmYuNmLu9Wbt92Yvw1LcpDc0RHaiojIsJye.gif)
- (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);
}
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLlR2bjlHcvN2LcNXZnFWbp9CXt92YuM3ZvxmYuNmLu9Wbt92Yvw1LcpDc0RHaiojIsJye.gif)
下面是具體的插入實作方法,
useTransaction為真代表使用事務處理,反之不使用
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLlR2bjlHcvN2LcNXZnFWbp9CXt92YuM3ZvxmYuNmLu9Wbt92Yvw1LcpDc0RHaiojIsJye.gif)
- (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];
}
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLlR2bjlHcvN2LcNXZnFWbp9CXt92YuM3ZvxmYuNmLu9Wbt92Yvw1LcpDc0RHaiojIsJye.gif)
最後将兩種方式的耗時進行對比(此結果在模拟器中運作)
從上面這些真實的資料來看,你就應該知道當你批量更新資料庫的時候應該利用事務處理!
總結:使用事務處理就是将所有任務執行完成以後将結果一次性送出到資料庫,如果此過程出現異常則會執行復原操作,這樣節省了大量的重複送出環節所浪費的時間