Estoy trabajando en una aplicación de iPhone que usa una base de datos sqlite. La aplicación descarga datos de Internet en una secuencia de fondo con la interfaz de usuario en el hilo principal. El hilo de descarga de fondo puede preformar INSERT, UPDATE y SELECT en la base de datos. La capa de IU también puede interactuar con la base de datos al hacer ACTUALIZACIONES y SELECCIONES. Si no interactúo mucho con la interfaz de usuario mientras se descarga el hilo de fondo, todo funciona bien. Sin embargo, comienzo a tener problemas cuando se realizan muchas ACTUALIZACIONES en el hilo principal (UI) mientras se realiza la descarga.problemas de concurrencia de sqlite
La aplicación siempre se cierra cuando intenta ejecutar una función de base de datos. Se cierra con EXC_BAD_ACCESS y no consigo ver ningún error. Por ejemplo, la última vez que dejó terminaba en 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);
No siempre renunció el sqlite3_step, a veces se deja en sqlite3_prepare_v2 o sqlite3_exec. He intentado poner estas declaraciones en un bucle y vuelve a intentarlo si no vuelve bien, pero que no funciona bien:
int returnCode = 0;
do{
returnCode = sqlite3_step(statement);
if(returnCode != SQLITE_DONE){
usleep(20);
}
}while(returnCode != SQLITE_DONE);
También he tratado de transacciones SQL, pero eso no hace ninguna diferencia . ¿Como puedo resolver esto? Parece que es un problema de concurrencia bastante básico, pero no he visto nada que me funcione.
Gracias por toda su ayuda, Justin
La aplicación se cierra * *? Para ser curioso, ¿es solo algún tipo de compilación específica de Apple? En vainilla Sqlite simplemente devuelve el error 'SQLITE_LOCKED' si hay contención, y también puede instalar un controlador ocupado para tomar decisiones sobre reintentos en estos casos. –