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 ); //提交事务
一次插入500条数据的时候,使用事务和不使用事务的时间相差 30倍。数据越多的话,差距的倍数就越大。所以如果数据量比较大的情况下,能使用事务还是尽量使用事务处理比较好。
通常一次 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倍。数据越多的话,差距的倍数就越大。所以如果数据量比较大的情况下,能使用事务还是尽量使用事务处理比较好。