2013-04-30 17 views
5

Nel metodo onCreate() della mia attività principale chiamo il costruttore del mio dbManager, chiamo la funzione open che crea un'istanza di SQLiteOpenHelper e chiamo su di esso lo getWritableDatabase(). All'interno di UIThread aggiungo record al database e li salva in ArrayList. Altri due thread controllano la roba di ArrayList e aggiornano la lista e il database. Ora voglio aggiungere un pulsante nell'interfaccia utente per eliminare sia il database che i record degli elenchi utilizzando uno AsyncTask. Ho letto che l'oggetto SqliteOpenHelper contiene una connessione al database. Quindi se c'è un'istanza di helper c'è solo una connessione db. Questa connessione può essere utilizzata da più thread e l'oggetto SqliteDatabase utilizza i blocchi java per mantenere la serializzazione dell'accesso. Quindi, se ho più thread che scrivono sul database, un thread attenderà che il precedente abbia completato la sua operazione?
L'aggiunta della nuova funzionalità (rimuovere tutto) potrebbe creare problemi, poiché devo evitare che uno dei due thread possa provare a modificare un record che non esiste più. Come posso raggiungere il mio obiettivo? Grazie.Android: thread multipli che scrivono sul database SQLite

+0

È necessario implementare il modello consumer e producer, questo aiuterà a creare una coda di richieste, non scrivere parallelamente al database. – IamStalker

+0

dipende da come si implementa la modifica, ma un aggiornamento sql restituisce n, dove n è il numero di elementi modificati, che può essere totalmente 0 se non esiste alcun record corrispondente alla clausola where. – njzk2

+0

1) Non si dovrebbero eseguire operazioni DB su Thread UI. 2) Avere solo un thread per leggere/scrivere l'ArrayList. @IamStalker perché non scrivere in parallelo al DB? – m0skit0

risposta

4

Il databese:

Finché si utilizza un solo aiutante, si sono sicuro, senza la necessità di fare qualcosa thread.
In un'app multi-thread, è necessario synchronized solo per la creazione dell'helper. È possibile utilizzare transacion se si desidera definire una sezione critica (più di un'operazione atomica).
Avvolgere ogni chiamata con getWritableDatabase() e close(false):

public void doSomething() { 
    SQLiteDatabase tdb = getWritableDatabase(); 
    dbInstance.writeSomething(tdb, 1); 
    close(false); 
} 

In questo modo ho più thread lettura e la scrittura nel database senza alcun problema.

È la logica app:

Usa memoria per tenere traccia di stato di un oggetto, e utilizzare il database come unica stoccaggio. Quindi, se un thread cancella le righe dal database, puoi immediatamente aggiornare gli oggetti in memoria e gestire il tuo ui di conseguenza.
Se i tuoi dati sono molto grandi, puoi tenere in memoria solo un SparseArray di id di righe sporche.
Potrebbe essere utile sincronizzare alcune operazioni qui.

+0

Dove si trova la sincronizzazione nel tuo pezzo di codice? – IamStalker

+0

L'helper del database sta eseguendo tutta la sincronizzazione necessaria per mantenere l'integrità del database. E non correlato al db - nella logica dell'app, potrebbe essere necessario che lo sviluppatore si sincronizzi attorno alle sezioni critiche del codice per mantenere l'integrità della logica aziendale. – auval

+0

Non esiste una tale limitazione, un centinaio di thread possono leggere e scrivere insieme nello stesso DB senza alcun problema. Usando un aiutante. Questo * non * dove si trova il problema quando si scrive un'app multi-thread. – auval

0

Quindi, se ho più thread di scrittura sul database, un filo sarà attendere che la precedente ha terminato la sua operazione?

Non è necessario. Vedi this per maggiori dettagli. Ad ogni modo, questo dipende dal motore DB e dovrebbe essere trasparente.

Aggiunta la nuova funzionalità (rimuovere tutti) potrebbe creare problemi, perché devo evitare che uno dei due fili può tentare di modificare un record che non esiste più. Come posso raggiungere il mio obiettivo?

Hanno solo un thread aggiornare il DB. Altri thread modificano solo lo ArrayList -anche lo si deve verificare perché ArrayList non è thread-safe, si consideri l'utilizzo di Collections#synchronizedList().

Problemi correlati