在多个线程中分离SQLite事务

时间:2014-12-12 11:20:05

标签: ios objective-c iphone database sqlite

我的应用程序的更新过程从三个不同的来源(例如,Twitter,Facebook和Google)获取数据。出于性能原因,我们在一个单独的线程中同时更新每个,并且希望每个人都有自己的SQLite事务,因为我们可能会同时处理~500个项目,这可能需要几秒钟。

有没有办法在一个没有"干扰"的线程中开始新的交易?与其他线程数据库的交互?

TLDR:你能跨不同的线程进行多个SQLite事务吗?


更新:例如,请考虑以下代码:

@implementation Update

- (void)prepareUpdate {
    [self update:@"Twitter"];
    [self update:@"Facebook"];
    [self update:@"Google"];
}

- (void)update:(NSString *)platform {
    dispatch_queue_t newThread = dispatch_queue_create("newThread", NULL);
    dispatch_async(newThread, ^{

        NSDictionary * data = [Platform getData:platform];

        [_db beginTransaction];
            for (id item in data) {
                [Platform update:platform withData:item];
            }
        [_db endTransaction];

        dispatch_async(dispatch_get_main_queue(), ^{

            NSLog(@"Update complete!");

        });
    });
}

@end

将产生以下错误:

Error whilst preparing query: cannot start a transaction within a transaction

2 个答案:

答案 0 :(得分:1)

SQLite每个连接有一个事务,因此要获得多个事务,您需要多个连接(即数据库对象)。

但是,multiple transactions to write to the database at the same time无法实现。

答案 1 :(得分:0)

已经提出了一个简单的问题
重播是肯定的,您可以跨不同的线程进行多个SQLite事务 Reference enter image description here

<小时/> 更多参考
Is SQLite threadsafe?
SQLite是线程安全的。我们做出这种让步,因为许多用户选择忽略前一段中给出的建议。但为了保证线程安全,必须在SQLITE_THREADSAFE预处理器宏设置为1的情况下编译SQLite。分发中的Windows和Linux预编译二进制文件都是以这种方式编译的。如果您不确定要链接的SQLite库是否被编译为线程安全,您可以调用sqlite3_threadsafe()接口来查找。

SQLite是线程安全的,因为它使用互斥锁来序列化对公共数据结构的访问。但是,获取和释放这些互斥锁的工作会使SQLite略微减慢。因此,如果您不需要SQLite是线程安全的,则应禁用互斥锁以获得最佳性能。有关其他信息,请参阅线程模式文档。

在Unix下,你不应该通过fork()系统调用将一个开放的SQLite数据库带入子进程 enter image description here
Reference