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

本文介绍如何通过使用SQLite事务来显著提高批量数据操作的速度,并提供了一个具体的iOS应用案例,展示了使用事务前后性能的显著差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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倍。数据越多的话,差距的倍数就越大。所以如果数据量比较大的情况下,能使用事务还是尽量使用事务处理比较好。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值