【发布时间】:2015-07-16 15:23:44
【问题描述】:
我相信我的用例相当普遍,但我找不到对此的权威答案。
我有一个在后台运行并将数据写入我的数据库的同步机制。这种同步可能需要很长时间(我使用 FTS)。为此,我使用FMDatabaseQueue。当我想读取数据库时,我使用同一个队列进行查询。
现在,当同步进程已经将大量事务排入队列时,应用想要执行读取操作,它必须等待所有写入事务完成才能执行查询,因为这是一个串行队列。代码可能如下所示:
FMDatabaseQueue *queue = [self getDatabaseQueue];
[queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
// Very slow process
[db executeUpdate:@"UPDATE docs SET name = ?", "value..."];
}];
[queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
// Very slow process
[db executeUpdate:@"UPDATE docs SET name = ?", "value..."];
}];
[queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
// Very slow process
[db executeUpdate:@"UPDATE docs SET name = ?", "value..."];
}];
[queue inDatabase:^(FMDatabase *db) {
FMResultSet *resultSet = [db executeQuery:@"SELECT name..."];
}];
我想立即获得查询结果(即使未完成同步),而不是等待UPDATE 完成。
我可以创建两个FMDatabaseQueues,一个用于写查询,一个用于读查询吗?如果读查询在写事务的中间开始会发生什么?
代码可能如下所示:
FMDatabaseQueue *writeQueue = [self getWriteDatabaseQueue];
FMDatabaseQueue *readQueue = [self getReadDatabaseQueue];
[writeQueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
// Very slow process
[db executeUpdate:@"UPDATE docs SET name = ?", "value..."];
}];
[writeQueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
// Very slow process
[db executeUpdate:@"UPDATE docs SET name = ?", "value..."];
}];
[writeQueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
// Very slow process
[db executeUpdate:@"UPDATE docs SET name = ?", "value..."];
}];
[readQueue inDatabase:^(FMDatabase *db) {
FMResultSet *resultSet = [db executeQuery:@"SELECT name..."];
}];
编辑:
此外,让我感到困惑的是文档中的说明:
每个线程都可以创建一个 FMDatabase 对象。只是不要跨线程共享单个实例。
所以我的理解是,我可以创建两个实例使用同一个数据库,但我只需要将其保留在自己的线程上。
【问题讨论】:
-
您尝试过自己的代码吗?乍一看,这看起来不错
-
我做到了,而且效果很好。我只是想知道我是否遗漏了什么,或者如果两个队列同时访问同一个数据库是否存在竞争条件。
-
不要相信我的话,但我很确定只要你不在两个队列上写,你应该没问题。您可以尝试使用 for 循环,例如 1000 次相同的更新语句,同时执行一些读取查询并查看它的反应,以确保确定。但从我记忆中的 FMDB 来看,我认为你可以边写边看
-
嗯,这不是一个真正的科学方法来找出...:/
-
统计是数学,数学是一种科学,对吧? :o 哈哈抱歉我不能给你更多我只是尽力而为,但最终我不知道下一个人的那么多
标签: ios objective-c sqlite fmdb