2016-11-27 6 views
0

Ich verwende SQLite last_insert_rowid(), um die zuletzt eingefügte Zeilen-ID nach einer Batch-Einfügung zu greifen. Besteht die Gefahr von Race Conditions, die dazu führen könnten, dass dieser Wert nicht die letzte ID des Batch-Einsatzes zurückgibt? Ist es beispielsweise möglich, dass zwischen dem Abschluss der Einfügung und dem Aufruf von last_insert_rowid() ein anderer Prozess wieder in die Tabelle geschrieben wurde?Abrufen von IDs von im Stapel eingefügten Zeilen in SQLite

Antwort

1

last_insert_rowid() gibt Informationen über die letzte Einfügung in dieser spezifischen Verbindung zurück; Es kann keinen Wert zurückgeben, der von einem anderen Prozess geschrieben wurde.

Um sicherzustellen, dass der zurückgegebene Wert dem aktuellen Status der Datenbank entspricht, nutzen Sie die ACID Garantien (hier: Atomizität) von SQLite: Umbrechen Sie die Stapeleinfügungen, den last_insert_rowid() Aufruf und was auch immer Sie mit der ID tun eine einzelne Transaktion.

In jedem Fall ändert sich der Rückgabewert von last_insert_rowid() nur, wenn einige Einfügevorgänge über diese Verbindung ausgeführt werden. Daher sollten Sie niemals auf dieselbe Verbindung aus mehreren Threads zugreifen, oder wenn Sie dies wirklich tun möchten, ganze Transaktionen serialisieren.

+1

Was ist mit @ Zso's Kommentar? Er schlägt ein Szenario vor, in dem mehrere Threads dieselbe Verbindung verwenden könnten. Würde eine Transaktion davor schützen? – maxedison

+0

Eine Verbindung = eine Transaktion, daher sollten Sie niemals auf dieselbe Verbindung von mehreren Threads zugreifen, unabhängig vom Threading-Modus. –

+0

Diese Antwort sollte nicht die akzeptierte sein, da sie über ** Prozesse ** spricht, aber das Risiko besteht in der Verwendung von ** Threads **. 'last_insert_rowid()' ist nicht notwendigerweise Multithread-sicher; Der Multi-Thread-Threading-Modus deaktiviert das Mutexing für Datenbankverbindungen. – Zso

1

last_insert_rowid() ist verbindungsabhängig, daher besteht ein Risiko, wenn mehrere Threads die gleiche Verbindung verwenden, ohne dass SQLite in den serialisierten Threading-Modus gewechselt hat.

+1

Wie schützt der serialisierte Thread-Modus vor diesem Problem? Verhindert es, dass mehrere Threads dieselbe Verbindung verwenden? – maxedison

+0

Nichts hindert Sie daran, mehrere Threads zu verwenden, aber SQLite befindet sich standardmäßig im Serialisierungsmodus. Es soll SQLite threadsafe sogar innerhalb der gleichen Datenbankverbindung über Mutexe machen. – Zso

+0

Ihre ursprüngliche Frage bezieht sich auf ** Prozesse **, aber Sie scheinen stattdessen an ** Threads ** interessiert zu sein. (Datenbankverbindungen können nicht zwischen Prozessen geteilt werden.) – Zso