it-swarm.com.de

Ist die Schnappschussisolation gut?

Meine Situation :

Tabelle: User { Id, Name, Stone, Gold, Wood }

Ich habe "write" Threads:

  • miningThread ( jede Minute)

UPDATE User SET Stone = @calculatedValue WHERE [email protected] UPDATE User SET Wood = @calculatedValue WHERE [email protected]

  • tradeThread ( jede Minute)

UPDATE User SET gold = @calculatedValue WHERE [email protected]

  • constructionThread ( jede Minute)

UPDATE User SET Wood = @calculatedValue WHERE [email protected] UPDATE User SET Stone= @calculatedValue WHERE [email protected]

Und haben "schreiben" Anfragen von Benutzern:

  • SellResource

UPDATE User SET Stone(Wood,Gold) = @calculatedValue WHERE [email protected]

(berechneWert wird durch C # -Business-Logikcode berechnet)

In diesem Fall habe ich viele Probleme mit "verlorenen Updates", wenn ich die Isolationsstufe read_commited_snapshot einstelle. Aber wenn ich serialisierbar oder Schnappschuss Level setze, funktionieren alle gut

Frage

Ich habe mir eine Tabelle zum Vergleich der Isolationsstufen angesehen und festgestellt, dass die Serialisierbarkeit und die Snapshot-Isolation alle Probleme bei gleichzeitigen Transaktionen lösen. Die Serialisierbarkeit ist jedoch sehr langsam.

  1. Kann ich die Snapshot-Isolation für alle Schreibtransaktionen verwenden? Ich will kein Chaos in meinen Tischen. Meine Geschäftslogik ist hart und ändert sich ständig.
  2. Hat die Snapshot-Isolation Fehler?
  3. Welche Isolationsstufe ist für schreibgeschützte Transaktionen besser?
7
GLeBaTi

Zusammenfassung:

Kann ich die Snapshot-Isolation für alle Schreibtransaktionen verwenden?

Ja, aber je nach Verwendung ist der gelesene Snapshot möglicherweise besser.

Hat die Snapshot-Isolation Fehler?

Ja. Es müssen Zeilenversionen aller aktiven Transaktionen gespeichert werden, für die Festplatte/Speicher erforderlich ist.

Welche Isolationsstufe ist für schreibgeschützte Transaktionen besser?

snapshot isolation, oder read committed snapshot abhängig davon, ob es mehrere Anweisungen gibt, die voneinander und von der Größe der Transaktion abhängen. read committed wenn es viele Updates gibt und Speicherplatz auf Tempdb ein Problem ist.

Tiefere Informationen

Welche Isolationsstufe verwendet werden soll, hängt von Ihrem Anwendungsfall ab und davon, wie Sie Ihre Daten innerhalb der Transaktionen verwenden. Beginnen wir also mit einem tieferen Vergleich der Ebenen.

Der SQL Server behält die Konsistenz bei, indem zwei verschiedene Techniken verwendet werden: Sperren und Zeilenversionierung.

Isolationsstufen sperren

Das Sperren funktioniert durch den SQL Server und gibt eine gemeinsame Sperre für die gelesenen Tabellen/Zeilen aus, wodurch andere Transaktionen daran gehindert werden, die Daten zu aktualisieren. Gleiches gilt für Aktualisierungen, die eine exklusive Sperre erhalten und andere Transaktionen daran hindern, die Daten zu lesen. Das Sperren erfolgt in verschiedenen Teilen der Datenbank, auf die ich nicht eingehen werde, sondern beispielsweise auf Tabellen, Zeilen und Indizes.

READ COMMITTED verwendet Sperren, um sicherzustellen, dass nur festgeschriebene Daten gelesen werden. Und dass keine anderen Transaktionen die Daten aktualisieren, während sie gelesen werden. Dies bedeutet, dass eine Aktualisierungsanweisung für Zeilen, die gerade von einer anderen Transaktion ausgewählt werden, blockiert wird. Eine select-Anweisung für Zeilen, die von einer anderen Transaktion aktualisiert werden, wird blockiert, bis diese Daten festgeschrieben werden.

READ UNCOMMITTED ignoriert alles und nimmt überhaupt keine Sperren. Dies bedeutet, dass eine andere Transaktion eine Aktualisierung für Zeilen durchführen kann, die die Transaktion gerade liest, ohne blockiert zu werden. Dies hat jedoch auch zur Folge, dass die Transaktion Daten empfängt, die die andere Transaktion möglicherweise noch nicht festgeschrieben hat.

SERIALISIERBAR das Gegenteil tun und alles sperren. Während READ COMMITTED die Sperren beim Lesen der Zeile oder beim Abschluss der Anweisung abhängig von der Sperre aufhebt, gibt SERIALIZABLE die Sperren frei, sobald die Transaktion festgeschrieben ist. Dies bedeutet, dass eine andere Transaktion, die Daten aktualisieren möchte, die die Transaktion mindestens einmal gelesen hat, oder eine andere Transaktion Daten lesen möchte, die die Transaktion aktualisiert hat, blockiert wird, bis die Transaktion festgeschrieben wird.

Isolationsstufen mit Zeilenversion

READ COMMITTED SNAPSHOT und SNAPSHOT ISOLATION verwenden stattdessen die Zeilenversionierung. Zeilenversionierung bedeutet, dass der SQL Server bei jeder Änderung einer Zeile eine Version der Zeile speichert, um sicherzustellen, dass diese beim Lesen durch eine andere Transaktion gleich bleibt.

SNAPSHOT ISOLATION funktioniert so, dass beim Lesen einer Tabelle die letzte Version der Zeilen abgerufen wird, die zum Zeitpunkt des Starts der Transaktion festgeschrieben wurden. Dies bietet eine konsistente Momentaufnahme der Daten innerhalb der Transaktion. Nach dem Start der Transaktion geänderte Daten sind nicht sichtbar, gleichzeitig wird die Transaktion jedoch nicht blockiert. Wenn die Transaktion zum Schutz vor verlorenen Aktualisierungen einige Zeilen aktualisieren möchte, die nach Beginn der Transaktion von einer anderen Transaktion geändert wurden, werden die Transaktionen aufgrund von Datenkonflikten beendet.

READ COMMITTED SNAPSHOT funktioniert genauso wie die Snapshot-Isolierung, aber anstatt den Snapshot während der gesamten Transaktion beizubehalten, wird er nur für die Dauer der Anweisung aufbewahrt. Dies bedeutet, dass zwei Leseanweisungen innerhalb einer Transaktion unterschiedliche Ergebnisse erhalten können. Wenn die Transaktion jedoch eine Aktualisierung durchführt, verwendet sie die tatsächliche Zeile anstelle einer vorherigen Zeilenversion und verfolgt nicht, ob die Zeile geändert wurde.

Da der SQL Server jede geänderte Zeile, die von aktiven Transaktionen verwendet werden könnte, verfügbar halten muss, speichert er sie in tempdb. Aus diesem Grund muss tempdb groß genug sein, um alle Änderungen zu berücksichtigen. Es gibt einen Hintergrundthread, der prüft, welche Zeilen noch benötigt werden, und den Rest entfernt. Wenn jedoch eine Transaktion mit langer Laufzeit ausgeführt wird, wird verhindert, dass diese Zeilen entfernt werden. Wenn in tempdb nicht mehr genügend Speicherplatz vorhanden ist, werden keine neuen Zeilenversionen erstellt, und alle Transaktionen, die versuchen, auf diese (nicht vorhandenen) Zeilen zuzugreifen, werden beendet.

Bemerkungen

READ COMMITTED SNAPSHOT ist neben READ UNCOMMITTED das freizügigste, wenn es um Parallelität geht. Es blockiert keine anderen DML-Anweisungen und behält eine konsistente Ansicht der Daten in jeder Anweisung bei.

  • SNAPSHOT ISOLATION ist zulässig und behält eine bessere Konsistenz bei als READ COMMITTED SNAPSHOT, mit dem Nachteil, dass aufgrund seiner Konfliktlösung beim Aktualisieren möglicherweise Fehler auftreten. Es ist garantiert, dass mehrere Anweisungen innerhalb derselben Transaktion miteinander konsistent sind.

  • READ COMMITTED ist zulässig, wenn es um gleichzeitige Lesevorgänge geht, nicht so sehr für Updates. Aufgrund der Sperrung ist es auch langsamer als die Zeilenversionsstufen.

  • READ UNCOMMITTED wird nicht empfohlen, da es schmutzige Daten liest. Wenn dies kein Problem darstellt, ist es am besten, wenn keine Sperren vorhanden sind und keine alten Zeilenversionen beibehalten werden müssen.

  • SERIALIZABLE wird nicht empfohlen, da es alles sperrt und daher langsam und nicht gut mit Parallelität ist.

12
Jimmy Stenke