gpt4 book ai didi

sqlite并发问题

转载 作者:IT王子 更新时间:2023-10-29 06:29:08 26 4
gpt4 key购买 nike

我正在开发一个使用 sqlite 数据库的 iPhone 应用程序。该应用程序在后台线程中从 Internet 下载数据,UI 在主线程中。后台下载线程可以在数据库上执行 INSERT、UPDATE 和 SELECT。 UI 层还可以通过执行 UPDATE 和 SELECT 与数据库交互。如果我在后台线程下载时不与 UI 进行大量交互,则一切正常。但是,当下载正在进行时在主 (UI) 线程上执行大量更新时,我开始遇到问题。

应用程序在尝试运行数据库功能时总是退出。它以 EXC_BAD_ACCESS 退出,我没有看到任何错误。例如,它最后一次退出在 sqlite3_step 结束:

    sqlite3_stmt *statement;
const char *query = "INSERT OR IGNORE INTO `names` (`id`,`name`) VALUES (?,?);";
if(sqlite3_prepare_v2(database, query, -1, &statement, NULL) != SQLITE_OK){
NSAssert1(0, @"Error while creating insert statement. '%s'", sqlite3_errmsg(database));
return NO;
}
sqlite3_bind_int(statement, 1, id);
sqlite3_bind_text(statement, 2, name, -1, SQLITE_TRANSIENT);

if(sqlite3_step(statement) != SQLITE_DONE)
NSAssert1(0, @"Error while inserting. '%s'", sqlite3_errmsg(database));

sqlite3_finalize(statement);

它并不总是在 sqlite3_step 上退出,有时它在 sqlite3_prepare_v2 或 sqlite3_exec 上退出。我试过将这些语句放在一个循环中,如果它没有返回 OK,再试一次,但这也不起作用:

int returnCode = 0;
do{
returnCode = sqlite3_step(statement);
if(returnCode != SQLITE_DONE){
usleep(20);
}
}while(returnCode != SQLITE_DONE);

我也尝试过 SQL 事务,但这没有任何区别。我该如何解决这个问题?这似乎是一个相当基本的并发问题,但我还没有看到任何对我有用的东西。

谢谢大家的帮助,贾斯汀

最佳答案

除非您使用特殊设置重新编译它,否则 SQLite 不是线程安全的。

参见 http://www.sqlite.org/faq.html#q6

因此,您需要负责从同一线程访问数据库并对其调用 SQL 操作。

但是,我想出了一个解决方案,即使在多线程环境中也似乎没问题:我确保任何 SQLite 操作都受到 @synchronized 指令的保护,以确保一旦一个线程正在数据库上做某事,任何其他线程都无法访问它。

因此,与其说“所有 SQlite 操作都应该在同一个线程中完成”,不如说“确保两个操作不会在不同线程中并行执行”。

关于sqlite并发问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2323684/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com