2013-04-18 6 views
5

In meiner Android-Anwendung muss ich Daten in verschiedene SQLite-Tabellen aus verschiedenen Threads einfügen (ein Thread zum Einfügen in eine Tabelle und 5 Tabellen). Es gibt eine Menge von Daten, so dass ich beginTransaction() ->setTransactionSuccessful() ->endTransaction(); in jedem Thread und alle Threads gleichzeitig starten, aber in der zweiten oder manchmal dritten Thread Ich habe immer diese Ausnahme:Kann keine Operation ausführen, da beim Einfügen in die Datenbank keine aktuelle Transaktion vorhanden ist.

enter image description here

Ich benutze einzelne SQLite-Verbindung (Singleton) wie mentioned here war, aber dennoch bleibt dieses Problem.So hoffe ich auf etwas Hilfe.Vielen Dank im Voraus!

P.S Und wenn ich Race Conditions habe, welchen anderen Weg sollte ich für Multithreading-Insertion verwenden?

Antwort

4

Ich denke, dein Problem ist eine Race Condition. Da Sie mehrere Threads haben, die die Transaktion beginnen und enden, könnten Sie so etwas wie die folgenden Operationen erhalten:

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() 

Ich glaube nicht, dass SQLite mehrere Transaktionen offen auf einer einzigen Verbindung unterstützt und wie Sie darauf hinweisen, Mehrfachverbindungen sind nicht möglich.

Wenn das Ziel der Transaktionen ist, die Daten zu beschleunigen, dann müssen Sie Ihre Architektur ändern und nicht aus mehreren Threads schreiben. Sie können eine Art Dienstprogrammklasse verwenden, um die tatsächlichen Datenbankaktualisierungen durchzuführen, die synchronized ist, so dass alle Threads aufrufen und es entscheidet, wann eine Transaktion geöffnet oder geschlossen wird. Eine andere Idee wäre, dass ein einzelner Thread Ihre Datenbankoperationen ausführt und alle anderen Threads in eine BlockingQueue schreiben, die mit dem schreibenden Thread geteilt wird.

+0

Ich habe ein paar Ideen zu meiner Antwort @AlexanderKaraberov hinzugefügt. – Gray

+0

Haben Sie eine Klasse (nur ein DAO), die diese tatsächliche Datenbank ändert. Dann würden Ihre Threads einfach 'insert()' oder ähnliches aufrufen. Die Methode würde "synchronisiert" und es würde entscheiden, ob ich die Transaktion starten muss, wenn sie nicht bereits gestartet wurde, oder eine Transaktion beenden, wenn sie bereits gestartet wurde. – Gray

Verwandte Themen