IOS-事务在数据库中的用处

来源:互联网 发布:忘记windows登陆密码 编辑:程序博客网 时间:2024/06/07 14:37
sqlite 是支持事务处理的。如果你知道你要同步删除很多数据,不仿把它们做成一个统一的事务。

通常一次 sqlite3_exec 就是一次事务,如果你要删除1万条数据,sqlite就做了1万次:开始新事务->删除一条数据->提交事务->开始新事务->… 的过程。这个操作是很慢的。因为时间都花在了开始事务、提交事务上。

你可以把这些同类操作做成一个事务,这样如果操作错误,还能够回滚事务。

事务的操作没有特别的接口函数,它就是一个普通的 sql 语句而已:

分别如下:

int result; 

result = sqlite3_exec( db, "begin transaction", 0, 0, &zErrorMsg ); //开始一个事务

result = sqlite3_exec( db, "commit transaction", 0, 0, &zErrorMsg ); //提交事务

result = sqlite3_exec( db, "rollback transaction", 0, 0, &zErrorMsg ); //回滚事务


这里我用的是FMDatabase;

#pragma mark -- (void) demoForTransaction{        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);    NSString *documentDirectory = [paths objectAtIndex:0];    NSString *databasePath = [documentDirectory stringByAppendingPathComponent:@"studentInfo.db"];        _database = [[FMDatabase alloc]initWithPath:databasePath];    if (![_database open]) {        NSLog(@"open fail");    }    [_database executeUpdate:@"create table if not exists student (Id text,Name text,Iphone text)"];    [_database close];        [self testDBSpeed];}- (void)insertData:(int)fromIndex useTransaction:(BOOL)useTransaction{    if ([_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 *phone= [[NSString alloc] initWithFormat:@"phone_%d",i];                    NSString *strName = [[NSString alloc] initWithFormat:@"name_%d",i];                    NSString *insertSql = @"INSERT INTO student(Id,Name,Iphone) VALUES (?,?,?)";                    BOOL a = [_database executeUpdate:insertSql,nId,strName,phone];                                        if (!a) {                        NSLog(@"插入失败1");                    }                    //                    NSString *deleteSql = @"DELETE FROM student WHERE Id=?";//                    BOOL b = [_database executeUpdate:deleteSql,nId];//                    if (!b) {//                        NSLog(@"删除失败1");//                    }else{//                        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 *phone= [[NSString alloc] initWithFormat:@"phone_%d",i];                NSString *strName = [[NSString alloc] initWithFormat:@"name_%d",i];                NSString *sql = @"INSERT INTO student(Id,Name,Iphone) VALUES (?,?,?)";                BOOL a = [_database executeUpdate:sql,nId,strName,phone];                if (!a) {                    NSLog(@"插入失败2");                }            }        }        [_database close];    }}-(void)testDBSpeed{    NSDate *date1 = [NSDate date];    [self insertData:500 useTransaction:NO];    NSDate *date2 = [NSDate date];    NSTimeInterval a = [date2 timeIntervalSince1970] - [date1 timeIntervalSince1970];    NSLog(@"不使用事务插入500条数据用时%.3f秒",a);    [self insertData:1000 useTransaction:YES];    NSDate *date3 = [NSDate date];    NSTimeInterval b = [date3 timeIntervalSince1970] - [date2 timeIntervalSince1970];    NSLog(@"使用事务插入500条数据用时%.3f秒",b);        /*     * 不使用事务插入500条数据用时0.291秒     * 使用事务插入500条数据用时0.009秒     */}

一次插入500条数据的时候,使用事务和不使用事务的时间相差 30倍。数据越多的话,差距的倍数就越大。所以如果数据量比较大的情况下,能使用事务还是尽量使用事务处理比较好。

1 0