2013-04-18 4 views
5

Nella mia applicazione Android devo inserire dati in diverse tabelle SQLite da diversi thread (un thread per l'inserimento in una tabella e ci sono 5 tabelle). Ci sono un sacco di dati in modo che uso beginTransaction() ->setTransactionSuccessful() ->endTransaction(); in ogni filo e tutti i thread iniziano contemporaneamente, ma in seconda o, talvolta, terzo filo Ho sempre avuto questa eccezione:Impossibile eseguire l'operazione perché non c'è transazione corrente quando si inserisce nel database

enter image description here

io uso singola connessione SQLite (singleton) come era mentioned here ma tuttavia questo problema rimane.Così spero in qualche aiuto.Grazie in anticipo!

P.S E se ho condizioni di gara quale altro modo dovrei usare per l'inserimento multithread?

risposta

4

Penso che il tuo problema sia una condizione di gara. Dal momento che si dispone di più thread che stanno iniziando e terminando la transazione, si potrebbe ottenere qualcosa di simile alle seguenti operazioni:

beginTransaction() 
// this may be a noop because a transaction is already open 
beginTransaction() 
setTransactionSuccessful() 
setTransactionSuccessful() 
endTransaction() 
// this may throw because the previous end closes the transaction 
endTransaction() 

Non credo che Sqlite supporta più transazioni aperto su una singola connessione e come fai notare, connessioni multiple non è possibile.

Se l'obiettivo delle transazioni è accelerare i dati, sarà necessario modificare l'architettura e non scrivere da più thread. È possibile utilizzare una sorta di classe di utilità per eseguire gli aggiornamenti effettivi del database synchronized in modo che tutti i thread chiamino e decida quando aprire o chiudere una transazione. Un'altra idea sarebbe quella di avere un singolo thread che le operazioni del database e tutti gli altri thread scrivano in un BlockingQueue condiviso con il thread di scrittura.

+0

Ho aggiunto alcune idee alla mia risposta @AlexanderKaraberov. – Gray

+0

Avere una classe (solo un DAO) che esegue le modifiche effettive del database. Quindi i tuoi thread chiamerebbero 'insert()' o alcuni di questi. Il metodo sarebbe 'sincronizzato' e deciderebbe se ho bisogno di avviare la transazione se non era già stata avviata o terminare una transazione se era già stata avviata. – Gray