我在我的应用程序中使用两种不同类型的fmdb连接:
所有READ查询的FMDatabase和所有UPDATE查询的FMDatabaseQueue.
两者都由一个单例处理,这使得两种类型在应用程序运行时保持打开状态.
读取和更新查询都在不同的线程中使用,因为我的应用程序中的某些任务是在后台进行的; 比如从服务器获取数据并通过FMDatabaseQueue在自己的后台线程中将其插入数据库 - 同时通过FMDatabase从db读取一些信息并在主线程上用它更新ViewController.
我的问题是,通过FMDatabaseQueue将数据插入数据库后,第二个连接(FMDatabase)不会返回更新的信息,因为它找不到它们.但我知道插入的数据是因为我使用db浏览器工具检查了数据库+插入时没有发生错误.为避免这种情况,我必须关闭FMDatabase数据库连接并重新打开它以查看其他连接所做的更改.不幸的是,当我的应用程序启动时,有许多插入,更新+读取,因为从服务器加载了许多需要处理的新数据 - 因此每次更新时关闭并打开数据库会发生在许多"数据库忙"消息.
我已经为所有线程使用了一个FMDatabaseQueue并执行(读取,更新)之前但是当使用__block变量的读取查询从回调中获取结果集而另一个线程执行一些插入(在50-100之间)时它非常慢单笔交易).
最重要的是,数据库是通过sqlcipher加密的 - 不确定它是否重要但是想要提及它.所以每次我必须关闭并打开数据库时,我正在做一个setKey.
我的问题:是否可以在多个线程上使用具有两种不同连接类型的设置,如果是,是否必须关闭并打开FMDatabase连接?或者这个用例有更好的解决方案吗?
我执行插入/更新的代码看起来像
-(void) create:(NSArray *)transactions
{
NSMutableString *sqlQuery = [[NSMutableString alloc] initWithString:STANDARD_INSERT_QUERY];
[sqlQuery appendString:@"(transaction_id, name, date) VALUES (?,?,?)"];
FMDBDataSource *ds = [FMDBDataSource sharedManager];
FMDatabaseQueue *queue = [ds getFMDBQ];
[queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
[db setKey:[ds getKey]]; // returns the key to decrypt the database
for (Transaction *transaction in transactions)
{
[db executeUpdate:sqlQuery, transaction.transactionId, transaction.name, transaction.date];
}
}];
}
Run Code Online (Sandbox Code Playgroud)
和一个读取查询
-(Transaction *)read:(NSString *)transactionId
{
NSString …Run Code Online (Sandbox Code Playgroud)