15 Stimmen

SQLite: Gemeinsame Nutzung von Verbindungen über Threads hinweg zum Lesen und Schreiben

Ich habe eine Anwendung, die SQLite (Version 3.7.2) zum Speichern von Daten verwendet. Ich habe eine SQLite-Verbindung, die von mehreren Threads geteilt wird, die in dieselbe SQLite-Datenbank schreiben und von ihr lesen. SQLite ist mit DSQLITE_THREADSAFE=1 kompiliert, was bedeutet, dass sich SQLite im Serialized-Modus befindet.

Zitiert von SQLite-Dokumente

Serienmäßig: Im serialisierten Modus kann SQLite sicher von mehreren Threads ohne Einschränkung verwendet werden.

Im Gegenteil, die SQLite-Wiki Eintrag sagt

D einem Thread

Ich habe es mit einer Beispielanwendung versucht, die Hunderte von Threads erzeugt und ein SQLite-Handle zum Lesen und Schreiben freigibt, was gut funktioniert.

Ist der SQLite-Wiki-Eintrag also veraltet oder kann SQLite möglicherweise nicht mit Lese- und Schreibvorgängen von verschiedenen Threads zur gleichen Zeit über dieselbe Verbindung umgehen?

10voto

Marcelo De Zen Punkte 9172

EDITAR

DSQLITE_THREADSAFE=2 : Multi-Thread-Modus Der Begriff "Multi-Thread" ist in SQLite ein wenig verwirrend. Es scheint, dass man im Multi-Thread-Modus eine Verbindung nicht mit anderen Threads teilen kann, weil die Verbindung selbst keine Mutexe verwendet, um zu verhindern, dass ein Thread die Verbindung ändert, während ein anderer Thread sie benutzt.

DSQLITE_THREADSAFE=1 : serialisierter Modus Allerdings ist in serialisiert Modus sperrt es die Datendatei und verwendet Mutexe, um den Zugriff auf die gemeinsame Verbindung zu kontrollieren.

Aus den Unterlagen: ... wenn SQLite mit SQLITE_THREADSAFE=1 kompiliert wird, serialisiert die SQLite-Bibliothek selbst den Zugriff auf Datenbankverbindungen und vorbereitete Anweisungen, so dass die Anwendung dieselbe Datenbankverbindung oder dieselbe vorbereitete Anweisung in verschiedenen Threads zur gleichen Zeit verwenden kann.

Also, wenn es um Verbindungen geht, serialisierter Modus es thread-safe pero Multi-Thread Modus nicht, obwohl Sie immer noch mehrere Verbindungen zu derselben Datenbank haben können.

Source : http://www.sqlite.org/c3ref/c_config_getmalloc.html#sqliteconfigmultithread

Herzliche Grüße!

0voto

Cinosarge Punkte 1

Es ist keine gute Idee, eine Verbindung auf mehrere Threads aufzuteilen, wenn Sie DSQLITE_THREADSAFE=0 haben.

Stellen Sie sich vor, Ihr THREAD 1 führt diesen Code aus:

1. connection.setAutoCommit(false);
2. statement.executeUpdate(sql);
3. connection.commit();

und Ihr THREAD 2 führt diesen Code zur gleichen Zeit aus:

1. connection.setAutoCommit(true);

Was passiert nun, wenn die Anweisung 1 von FADEN 2 genau VOR der Anweisung 3 von FADEN 1 ausgeführt wird? Sie erhalten wahrscheinlich eine SQLException mit der Meldung "database in auto-commit mode" (da die auto-commit-Methoden auf demselben Connection-Objekt ausgeführt werden).

Das heißt, man sollte seinen Code synchronisieren oder DSQLITE_THREADSAFE=1 verwenden.

Die Verwendung von Connection Pooling wäre auch das Beste, wenn Sie Multithread-Code entwickeln wollen, mit dem Sie eine bessere Leistung erzielen können, wenn Sie sich für ein anderes DBMS entscheiden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X