Inkonsistenz beim wiederholbaren Lesen

10

http://www.postgresql.org/docs/9.2/static/transaction-iso.html

Der wiederholbare Lesemodus bietet eine strenge Garantie dafür, dass jede Transaktion eine vollständig stabile Ansicht der Datenbank sieht. Diese Ansicht ist jedoch nicht unbedingt immer mit einer seriellen (einzelnen) Ausführung gleichzeitiger Transaktionen derselben Ebene konsistent. Beispielsweise wird bei einer schreibgeschützten Transaktion auf dieser Ebene möglicherweise ein Kontrolldatensatz aktualisiert, um anzuzeigen, dass ein Stapel abgeschlossen wurde, jedoch nicht einer der Detaildatensätze, der logisch Teil des Stapels ist, da eine frühere Revision des Kontrolldatensatzes gelesen wurde . Versuche, Geschäftsregeln durch Transaktionen durchzusetzen, die auf dieser Isolationsstufe ausgeführt werden, funktionieren ohne sorgfältige Verwendung expliziter Sperren zum Blockieren widersprüchlicher Transaktionen wahrscheinlich nicht ordnungsgemäß.

Ist das nicht ein Phantom-Lesevorgang, der im wiederholbaren Lesemodus nicht möglich ist?

Die Dokumentation besagt, dass eine Abfrage in einer wiederholten Lesetransaktion zu Beginn der Transaktion einen Snapshot sieht. Wie kann es dann möglich sein, dass eine Abfrage inkonsistente Daten liest?

Alice
quelle

Antworten:

5

Hier ist meine Lektüre dieses Abschnitts. Ich gebe zu, es ist verwirrend.

Angenommen, ich habe zwei Tabellen:

CREATE TABLE batch (
   id serial not null unique,
   control_code text primary key,
   date_posted date not null default now()
);

CREATE TABLE details (
   batch_id int not null references batch(id),
   description text,
   primary key(batch_id, description)
);

Angenommen, wir fügen Stapel- und Detaildatensätze in verschiedene Transaktionen ein. Sitzung 1 fügt einen Stapel ein und beginnt mit dem Einfügen von Details. Vor Abschluss von Sitzung 2 wird Sitzung 2 gestartet. In Sitzung 2 werden die Informationen zur Stapelüberschrift angezeigt, es wird jedoch nicht auf die Festschreibung von Details gewartet, um den Benutzer darüber zu informieren, dass keine Datensätze gefunden wurden. Wenn sich Ihr Stapel und Ihre Daten vollständig in derselben Transaktion befinden, ist dies nie ein Problem.

Dies würde sich von der Serialisierbarkeit unterscheiden, bei der Sie erwarten würden, dass die vorherige Einfügung abgeschlossen und festgeschrieben oder zurückgesetzt wird, bevor festgelegt wird, ob der Benutzer benachrichtigt werden soll, dass keine Zeilen gefunden wurden.

Chris Travers
quelle
3

Im PostgreSQL-Wiki gibt es ein Dokument, das einige Probleme aufzeigt, die bei bestimmten Kombinationen von Transaktionen auf der Transaktionsisolationsstufe REPEATABLE READ auftreten können, und wie sie auf der Transaktionsisolationsstufe SERIALIZABLE ab PostgreSQL Version 9.1 vermieden werden.

Es enthält auch ein Beispiel dafür, wie es möglich sein könnte, dass eine READ-ONLY-Transaktion auf REPEATABLE READ-Ebene inkonsistente Daten liest.

907 ..
quelle
@dezso Das könnte Sie interessieren
907.
1

Phantom-Lesevorgänge (stellen Sie sicher, dass Sie dies nicht mit nicht wiederholbaren Lesevorgängen verwechseln) sind in der Isolationsstufe "Wiederholbarer Lesevorgang" möglich ... im Prinzip. Das De-facto-Verhalten von Postgresql bei Auswahl von "Wiederholbares Lesen" ist jedoch stärker als der Standard (fast eine "serialisierbare" Isolation), sodass Sie tatsächlich keine Phantom-Lesevorgänge haben. Docs :

Wenn Sie die Stufe Read Uncommitted auswählen, wird Read Committed wirklich aktiviert, und Phantom Reads sind in der PostgreSQL-Implementierung von Repeatable Read nicht möglich , sodass die tatsächliche Isolationsstufe möglicherweise strenger ist als die von Ihnen ausgewählte.

Was ist nun mit dieser Einschränkung "Diese Ansicht wird nicht unbedingt immer mit einer seriellen (einer nach der anderen) Ausführung gleichzeitiger Transaktionen derselben Ebene übereinstimmen"? Ich denke (ich bin mir nicht sicher), dass dies bedeutet, dass der Snapshot "von außen" (zu Beginn der Transaktion behoben) möglicherweise Zeilen aus anderen Transaktionen enthalten kann, aber einige andere Zeilen aus derselben Transaktion nicht enthält.

leonbloy
quelle