2010-03-07 11 views
16

Sto sviluppando un'applicazione Android. Ha più thread che leggono e scrivono nel database SQLite di Android. Sto ricevendo il seguente errore:Come evitare errori di blocco SQLiteException

SQLiteException: error code 5: database is locked

Capisco la SQLite blocca l'intero db sull'inserimento/aggiornamento, ma questi errori sembrano accadere solo quando si inseriscono/aggiornamento, mentre sono in esecuzione una query di selezione. La query select restituisce un cursore che viene lasciato aperto piuttosto un wile (qualche secondo qualche volta) mentre lo iterò sopra. Se la query di selezione non è in esecuzione, non ottengo mai i blocchi. Sono sorpreso che la selezione potrebbe bloccare il db. È possibile o è in corso qualcos'altro?

Qual è il modo migliore per evitare tali blocchi?

+0

Lei dice lasciando il cursore aperto per un po '. Credo di avere lo stesso problema, ma i miei cursori sono gestiti da un listView. Sei mai riuscito a risolvere questo problema? – taer

+1

Sì, ho risolto questo problema leggendo immediatamente il contenuto del cursore in una raccolta, chiudendo il cursore e quindi iterando sulla raccolta per eseguire il lavoro che richiede molto tempo. Se stai usando un listView, dovresti essere in grado di fare lo stesso e usare un ArrayAdapter o scrivere il tuo adattatore estendendo ArrayAdapter. – TheArchedOne

+0

http://stackoverflow.com/questions/7657223/sqlite-exception-database-is-locked-issue/9503044#9503044 – junto

risposta

2

Evitando di lasciare i cursori aperti per "un po '". Se puoi permetterti di avere tutti i tuoi dati in memoria tutti in una volta, allora fallo.

Se non è possibile, provare ad aumentare il timeout occupato.

1

Migrare a ContentProvider anziché accedere direttamente al DB. ContentResolver risolve tutti i problemi di threading e consente anche altre funzionalità utili come la condivisione dei dati tra le app o la sincronizzazione con un server.

L'overhead delle API di ContentResolver è minimo. Devi solo definire una stringa AUTHORITY (una stringa univoca che identifica il "tipo" dei tuoi dati - usa un tipo di stringa "com.example.myapp.contacts") e usa ContentResolver.bla piuttosto che db.bla.

7

Probabilmente stai aprendo e chiudendo più connessioni al database nei vari thread. Questa è una cattiva idea. Basta aprire una singola connessione al database e riutilizzarla ovunque; SQLite assicurerà quindi che gli accessi simultanei siano serializzati correttamente.

Come per la risposta di jcwenger, l'utilizzo di ContentProvider è un altro modo per ottenere questo risultato, ma richiede molte più modifiche invadenti al codice.

+0

Non sto aprendo e chiudendo il database più volte, anche se sto ricevendo questo errore per favore prenda un guarda [link is here] (http://stackoverflow.com/questions/13859840/application-crashes-on-installation-with-error-sqlite3-exec-failed-to-set-sync) – MobileEvangelist

0

sua causata da beginTransaction() function.Look al vostro codice, il problema è risolto per la mia app per fare una riga di commento questa funzione (beginTransaction) Linea

Problemi correlati