Qualcuno può fornire qualsiasi input su questo errore. Sto cercando di inserire nella tabella utilizzando l'obiettivo C.SQLite Eccezione: SQLite Occupato
Mentre eseguo ciò, viene visualizzato un errore SQLite Occupato. Perché questo sta accadendo?
Qualcuno può fornire qualsiasi input su questo errore. Sto cercando di inserire nella tabella utilizzando l'obiettivo C.SQLite Eccezione: SQLite Occupato
Mentre eseguo ciò, viene visualizzato un errore SQLite Occupato. Perché questo sta accadendo?
Se ho capito bene, "occupato" significa che non è possibile ottenere un blocco. Sembra che qualche altro processo (o thread, ecc.) Abbia un blocco su un database.
Se si ottiene come risultato quando si invoca una funzione sqlite3 il codice di errore SQLITE_BUSY, questo significa che come osservato da drdaeman che il db è stato bloccato dallo stesso processo o da un thread all'interno del vostro processo.
Il modo corretto per affrontare questa situazione è quello di provare l'operazione in un ciclo, e se il codice di ritorno è ancora SQLITE_BUSY, attendere per qualche tempo (si decide il valore di timeout) e quindi ripetere l'operazione nel prossimo loop iterazione.
Per esempio, il seguente frammento di codice è tratto dal FMDB Objective C involucro (http://code.google.com/p/flycode/source/browse/trunk/fmdb) mostra come preparare una dichiarazione per una query tenendo conto che alcune operazioni possono restituire SQLITE_BUSY:
int numberOfRetries = 0;
BOOL retry = NO;
if (!pStmt) {
do {
retry = NO;
rc = sqlite3_prepare(db, [sql UTF8String], -1, &pStmt, 0);
if (SQLITE_BUSY == rc) {
retry = YES;
usleep(20);
if (busyRetryTimeout && (numberOfRetries++ > busyRetryTimeout)) {
NSLog(@"%s:%d Database busy (%@)", __FUNCTION__, __LINE__, [self databasePath]);
NSLog(@"Database busy");
sqlite3_finalize(pStmt);
[self setInUse:NO];
return nil;
}
}
else if (SQLITE_OK != rc) {
if (logsErrors) {
NSLog(@"DB Error: %d \"%@\"", [self lastErrorCode], [self lastErrorMessage]);
NSLog(@"DB Query: %@", sql);
if (crashOnErrors) {
NSAssert2(false, @"DB Error: %d \"%@\"", [self lastErrorCode], [self lastErrorMessage]);
}
}
sqlite3_finalize(pStmt);
[self setInUse:NO];
return nil;
}
}
while (retry);
}
A modo, se hai bisogno di accedere a sqlite, FMDB è molto pratico e molto più semplice da usare rispetto all'accesso diretto attraverso le API C native.
È possibile ottenere praticamente la stessa cosa semplicemente chiamando [sqlite3_busy_timeout] (http://www.sqlite.org/c3ref/busy_timeout.html). –
Downvoted. Primo, se qualcuno sta facendo una cosa, anche in un progetto open source, non implica che sia una "cosa giusta". Una cosa veramente appropriata è qualcosa che viene indicato nella documentazione dagli autori della biblioteca in questione. http://www.sqlite.org/c3ref/busy_handler.html –
@Alaksiej N: hai letto attentamente la documentazione per il gestore occupato che hai fornito nel tuo commento? Viene visualizzato quanto segue: "La presenza di un gestore occupato non garantisce che verrà richiamata in caso di conflitto di blocco. Se SQLite determina che il richiamo del gestore occupato può provocare un deadlock, continuerà a restituire SQLITE_BUSY o SQLITE_IOERR_BLOCKED anziché richiamare l'operatore impegnato. " Pertanto, non vi è alcuna garanzia che SQLite invocherà sempre il gestore occupato che si definisce! –
Ho avuto un problema simile con SQLITE_BUSY su comandi INSERT INTO sequenziali. La prima riga è stata inserita correttamente, ma quando l'app ha provato a inserire una seconda riga, ho ottenuto lo stato SQLITE_BUSY. Dopo aver fatto il giro di Google, ho appreso che devi chiamare sqlite3_finalize() sulle istruzioni dopo averle eseguite: http://www.sqlite.org/c3ref/finalize.html. La conclusione delle mie affermazioni ha risolto il mio problema.
Nel mio caso, avevo dimenticato di chiudere il database dopo averlo utilizzato. Dopo la mia fissa:
sqlite3_finalize(statement);
sqlite3_close(contactDB);
FMDB può anche alleviare questi mal di testa da voi facilmente.
Era semplice come eseguire prompt dei comandi come amministratore per me. In alternativa su UNIX potresti essere in grado di utilizzare sudo
all'avvio del database.
puoi fornire qualche codice di esempio? Un paio di righe per capire cosa sta succedendo. – stefanB