面试题答案
一键面试开启事务确保数据一致性
在FMDB中,通过FMDatabase
对象开启事务。事务可以将一组数据库操作作为一个原子单元,要么全部成功,要么全部失败,从而确保数据的一致性。具体步骤如下:
- 打开数据库连接。
- 调用
beginTransaction
方法开启事务。 - 执行批量插入操作。
- 如果所有插入操作成功,调用
commit
方法提交事务;如果有任何操作失败,调用rollback
方法回滚事务。
示例代码优化批量插入过程提高效率
以下是示例代码:
#import "ViewController.h"
#import "FMDB.h"
@interface ViewController ()
@property (nonatomic, strong) FMDatabase *database;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 数据库文件路径
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *databasePath = [documentsPath stringByAppendingPathComponent:@"test.db"];
self.database = [FMDatabase databaseWithPath:databasePath];
if (![self.database open]) {
NSLog(@"数据库打开失败");
return;
}
// 创建表
NSString *createTableSQL = @"CREATE TABLE IF NOT EXISTS largeTable (id INTEGER PRIMARY KEY AUTOINCREMENT, data TEXT)";
if (![self.database executeUpdate:createTableSQL]) {
NSLog(@"创建表失败");
[self.database close];
return;
}
// 模拟大量数据
NSMutableArray *dataArray = [NSMutableArray array];
for (int i = 0; i < 10000; i++) {
NSString *data = [NSString stringWithFormat:@"Data %d", i];
[dataArray addObject:data];
}
// 批量插入数据
[self batchInsertData:dataArray];
[self.database close];
}
- (void)batchInsertData:(NSArray *)dataArray {
[self.database beginTransaction];
@try {
for (NSString *data in dataArray) {
NSString *insertSQL = @"INSERT INTO largeTable (data) VALUES (?)";
if (![self.database executeUpdate:insertSQL, data]) {
@throw [NSException exceptionWithName:@"InsertError" reason:@"插入数据失败" userInfo:nil];
}
}
[self.database commit];
NSLog(@"批量插入成功");
} @catch (NSException *exception) {
[self.database rollback];
NSLog(@"批量插入失败: %@", exception.reason);
} @finally {
// 可以在这里进行一些清理操作
}
}
@end
优化说明
- 使用事务:将所有插入操作放在一个事务中,确保数据的一致性。如果某个插入操作失败,整个事务会回滚,不会造成部分数据插入成功的情况。
- 减少SQL语句解析次数:在循环中使用同一个
INSERT
语句模板,通过?
占位符来替换实际数据,这样数据库只需要解析一次SQL语句,提高效率。 - 批量提交:避免每次插入后单独提交,而是在所有插入操作完成后一次性提交事务,减少磁盘I/O操作次数。