Я работаю над iPhone-приложением, которое использует базу данных sqlite. Приложение загружает данные из Интернета в фоновый поток с пользовательским интерфейсом в основном потоке. В потоке загрузки фона можно занести в базу данных INSERT, UPDATE и SELECT. Уровень пользовательского интерфейса также может взаимодействовать с базой данных, выполняя UPDATE и SELECT. Если я не сильно взаимодействую с пользовательским интерфейсом, когда загружается фоновый поток, все работает нормально. Тем не менее, я начинаю сталкиваться с проблемами, когда во время загрузки происходит много UPDATE в основном (UI) потоке.sqlite проблемы параллелизма
Приложение всегда завершает работу, когда пытается запустить функцию базы данных. Он завершает работу с 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. Я пытался поставить эти заявления в петлю и повторите попытку, если она не возвращается в порядке, но это не работает, либо:
int returnCode = 0;
do{
returnCode = sqlite3_step(statement);
if(returnCode != SQLITE_DONE){
usleep(20);
}
}while(returnCode != SQLITE_DONE);
Я также попытался транзакции SQL, но это не имеет никакого значения , Как я могу это решить? Похоже, что это довольно простая проблема параллелизма, но я не видел ничего, что работает для меня.
Спасибо за вашу помощь, Джастин
приложение * * квиты? Просто быть любопытным, это просто какая-то конкретная сборка Apple? В ванильном Sqlite он просто возвращает ошибку SQLITE_LOCKED, если есть конфликт, и вы также можете установить обработчик занятости для принятия решений о повторных попытках в этих случаях. –