Alle Originalinhalte werden auf Ukrainisch erstellt. Noch nicht alle Inhalte wurden übersetzt. Einige Beiträge sind möglicherweise nur auf Ukrainisch verfügbar.Mehr erfahren

Pessimistische Sperre in Rails: was ist das und wann sollte man sie anwenden? Welche Alternativen gibt es?

Beitrags-Cover: Pessimistische Sperre in Rails: was ist das und wann sollte man sie anwenden? Welche Alternativen gibt es?
Dieser Inhalt wurde automatisch aus dem Ukrainischen übersetzt.
Wenn Sie mit Rails arbeiten und gleichzeitig eine Änderung eines Datensatzes durch mehrere Prozesse vermeiden müssen, sollten Sie auf den Mechanismus der Datensatzsperrung in der Datenbank achten. Eine der zuverlässigsten Methoden, dies zu tun, ist pessimistische Sperrung.

Was ist eine pessimistische Sperre?

Eine pessimistische Sperre bedeutet, dass der Datensatz in der Datenbank physisch für Änderungen von anderen Threads oder Prozessen blockiert wird, bis die aktuelle Operation abgeschlossen ist. Das heißt, wenn ein Prozess eine Sperre auf den Datensatz erhalten hat, müssen die anderen warten, bis er sie freigibt.
In ActiveRecord wird die pessimistische Sperrung durch die Methode lock implementiert, die SELECT ... FOR UPDATE hinzufügt, die die Sperre bis zum Ende der Transaktion hält.

Verwendung in Rails

Hier ist ein einfaches Beispiel für die Verwendung von lock in Rails:
ActiveRecord::Base.transaction do
  order = Order.lock.find(order_id)
  order.status = "processed"
  order.save!
end
In diesem Fall, wenn ein anderer Prozess versucht, die Bestellung mit derselben order_id zu erhalten, muss er warten, bis der aktuelle Prozess die Transaktion abgeschlossen hat.

Warum ist das notwendig?

Stellen wir uns vor, wir bearbeiten Bestellungen. Wenn der Benutzer auf die Schaltfläche "Bezahlen" klickt, müssen wir die Menge des Produkts im Lager verringern. Wenn mehrere Personen gleichzeitig versuchen, die letzte Einheit des Produkts zu kaufen, kann ohne Sperrung ein Race Condition auftreten:
  1. Prozess 1 liest die Menge des Produkts (1 Einheit).
  2. Prozess 2 liest dieselbe Menge (1 Einheit).
  3. Beide Prozesse versuchen, den neuen Wert (0 Einheiten) zu schreiben.
  4. Einer der Prozesse verliert das Update des anderen.
Wenn jedoch lock verwendet wird, muss der zweite Prozess warten, bis der erste abgeschlossen ist, bevor er entscheidet, was zu tun ist.

Alternativen zur pessimistischen Sperre

Pessimistische Sperrung ist nicht immer die beste Wahl, da sie andere Prozesse blockieren kann und die Leistung der Anwendung verlangsamt. Manchmal ist es besser,:
  1. Optimistische Sperrung — überprüft, ob sich der Datensatz zwischen Lesen und Schreiben geändert hat.
  2. Atomare Operationen — verwendet UPDATE ... WHERE oder increment! ohne Werte in Ruby zu lesen.
  3. Warteschlangenbasierter Ansatz — verteilt Updates über eine Warteschlange (Sidekiq, RabbitMQ).

Optimistische Sperrung in Rails

Optimistische Sperrung funktioniert über die Spalte lock_version. Wenn zwei Prozesse einen Datensatz lesen, überprüft das System beim Versuch, Änderungen zu schreiben, ob sich der Datensatz in der Zwischenzeit geändert hat:
class Order < ApplicationRecord
  attr_accessor :lock_version
end
Wenn dann ein Prozess Änderungen vornimmt und ein anderer versucht, eine veraltete Version zu schreiben, erhält er ActiveRecord::StaleObjectError.
Einfach gesagt:
  • Pessimistische Sperrung blockiert den Datensatz, um Konflikte zu vermeiden.
  • Optimistische Sperrung ermöglicht das Arbeiten ohne Sperrung, erfordert jedoch die Behandlung von Konflikten.
  • Atomare Operationen verringern das Risiko von Race Conditions ohne Sperrungen.
Wählen Sie den richtigen Ansatz je nach Aufgabe. Wenn es kritisch ist, Konflikte um jeden Preis zu vermeiden — verwenden Sie lock. Wenn die Leistung wichtig ist und Konflikte toleriert werden können — ist lock_version oder atomare Updates besser.

Dieser Beitrag hat noch keine Ergänzungen vom Autor.

Die Struktur von Promise (JavaScript) und wie man damit arbeitet
18. Feb, 14:33 Uhr

Die Struktur von Promise (JavaScript) und wie man damit arbeitet

meme code
meme code@memecode
Was ist Memoization (Beispiele für Ruby und Ruby on Rails)?
20. Feb, 18:16 Uhr

Was ist Memoization (Beispiele für Ruby und Ruby on Rails)?

meme code
meme code@memecode
Was ist Debounce in JavaScript und warum ist es wichtig?
21. Mär, 16:39 Uhr

Was ist Debounce in JavaScript und warum ist es wichtig?

meme code
meme code@memecode
Was ist CFB (Cipher Feedback)?
21. Mär, 16:53 Uhr

Was ist CFB (Cipher Feedback)?

meme code
meme code@memecode
Was ist XOR und wie funktioniert es?
21. Mär, 17:05 Uhr

Was ist XOR und wie funktioniert es?

meme code
meme code@memecode
Embedded-Programmierung: Was ist das und wo fängt man an
24. Mär, 16:48 Uhr

Embedded-Programmierung: Was ist das und wo fängt man an

meme code
meme code@memecode
Warum überspringt PostgreSQL die ID beim Speichern neuer Einträge? (Heroku)
31. Mär, 19:13 Uhr

Warum überspringt PostgreSQL die ID beim Speichern neuer Einträge? (Heroku)

meme code
meme code@memecode
[Codecov] Was ist der Unterschied zwischen Patch- und Projektabdeckung?
09. Apr, 16:03 Uhr

[Codecov] Was ist der Unterschied zwischen Patch- und Projektabdeckung?

meme code
meme code@memecode
Wie helfen Scratch-Kurse Kindern, Soft Skills zu entwickeln?
11. Apr, 18:24 Uhr

Wie helfen Scratch-Kurse Kindern, Soft Skills zu entwickeln?

meme code
meme code@memecode
24. Apr, 20:17 Uhr

Wir fixieren minikube "Sie versuchen, die amd64-Binärdatei auf einem M1-System auszuführen."

meme code
meme code@memecode
24. Apr, 20:55 Uhr

Wir fixieren minikube auf dem Mac mit M1 (wir verzichten auf qemu, starten auf docker)

meme code
meme code@memecode
Wo findet man eine ältere Version von Google Chrome und lädt sie herunter? Am Beispiel eines alten Macs.
25. Apr, 23:02 Uhr

Wo findet man eine ältere Version von Google Chrome und lädt sie herunter? Am Beispiel eines alten Macs.

meme code
meme code@memecode