SQLite-Verbindungen und Sperren

8

Ich möchte von zwei verschiedenen Threads auf eine SQLite-Datenbank zugreifen und dabei zwei verschiedene Verbindungen zur Datenbank verwenden. Beide Threads führen hauptsächlich Lesevorgänge aus der DB aus und schreiben nur gelegentlich in die DB. Wenn ich der Meinung bin, dass die Chancen gegen beide Threads sind, die gleichzeitig an die Datenbank schreiben, sollte ich mich sicher fühlen, dass ich in diesem Szenario keine Probleme haben sollte?

    
Drake Amara 03.11.2011, 00:41
quelle

3 Antworten

6

SQLite ist threadsafe und mit neueren Versionen können Sie eine einzelne Verbindung zwischen Threads teilen. Das heißt, die SQLite FAQ sagt "Threads Are Evil" (ich glaube nicht, dass sie das im Kontext von SQLite meinen, sondern als allgemeine Aussage).

SQLite verfügt über Sperrmechanismen, sodass selbst dann, wenn eine zweite Instanz versucht, eine Schreibsperre für die Datenbank zu erhalten, diese in die Warteschlange gestellt wird, bis die vorhandenen Sperren abgeschlossen sind. Die FAQ legen nahe, dass es im Allgemeinen nicht sicher ist, mehrere Verbindungen von verschiedenen Prozessen auf Netzwerk-Dateisystemen zu verwenden, weil die Sperre im Dateisystem schlecht implementiert ist, aber ich denke nicht Diese Warnung gilt für Ihre Verwendung.

    
Larry Lustig 03.11.2011, 01:00
quelle
9

Nicht ganz richtig. Bitte sehen Sie meine lange Antwort hier:

Was sind die besten Praktiken für SQLite auf Android? ?

Sie werden Ihre Datenbank nicht beschädigen, aber wenn zwei verschiedene Threads mit zwei verschiedenen Verbindungen versuchen, gleichzeitig in die db zu schreiben, werden Sie Probleme haben. Man wird "verlieren". Sie werden nicht warten, bis sie in Ordnung sind. Wenn Sie 'insert' anstelle von 'insertOrThrow' aufrufen, erhalten Sie nicht einmal eine Ausnahme. Sie werden einfach nicht in die DB schreiben.

So funktioniert Sqlite in Android. Jede SqliteOpenHelper-Instanz hat eine Verbindung zur Datenbank. Es spielt keine Rolle, wie oft Sie 'getRead / WriteableDatabase' aufrufen. Ein Helfer, eine Verbindung. Außerdem implementiert der sqlite-Verbindungscode von Android seine eigene Thread-Sperrung. Wenn Sie also denselben SqliteOpenHelper und damit dieselbe Verbindung verwenden, ist alles in Ordnung.

Wenn Sie jedoch mehr als einen Helfer verwenden, können Sie auf eine schlechte Art und Weise sein.

Ich vermute, du könntest mehrere Threads lesen und schreiben lassen, und komm raus, OK, aber ich habe das nicht getestet.

Verwenden Sie mehrere Threads für die Schreibleistung? Wenn ja, würde ich vorschlagen, einfach Ihre Verwendung von "Transaktionen" zu optimieren. Wenn Sie mehrere unabhängige Schreibvorgänge ausführen, ist SEHR langsam. Wenn Sie alle in einem Stapel verpacken, ist es sehr schnell (relativ). Ich vermute, das liegt daran, dass Android mit jedem unabhängigen Schreibvorgang auf die Festplatte (die sehr langsam ist) gespült wird. Wenn Sie sie in einem Haufen machen, werden die Änderungen alle in 1 Schreibweise vorgenommen.

Was die Pflege von 1 Hilfsinstanz anbelangt, hier ist ein neuer Blogbeitrag von mir:

Ссылка

Ich hatte eine ziemlich komplexe Referenzzähllogik als Teil meiner frühen Implementierung von OrmLite Android Port geschrieben, aber ich denke nicht, dass das alles an diesem Punkt notwendig ist.

Ссылка

Zur Vollständigkeit in Links, mein Blog-Post über SQLite-Sperrung und mehrere Verbindungen:

Ссылка

    
Kevin Galligan 03.11.2011 01:10
quelle
0

SQLite ist explizit nicht Thread-sicher, daher können Sie mit Datenverlust rechnen, wenn Sie dies tun.

Verwenden Sie mutex locking, um sicherzustellen, dass beide Threads nicht gleichzeitig auf die Datenbank zugreifen können, oder verbringen Sie Stunden damit, Phantomdaten-Verfälschungsfehler ausfindig zu machen, die nur selten auftreten und schwer reproduzierbar sind.

Ссылка

    
Meleneth 03.11.2011 00:45
quelle

Tags und Links