← strona głównaProgramowanie (Програмування)

Pessimistic Lock w Rails: co to jest i kiedy stosować. Jakie są alternatywy?

Dowiedz się, jak używać pessimistic lock w Rails, aby chronić przed jednoczesnymi zmianami rekordów. Porównujemy z optimistic locking i atomic updates.

Spis treściKliknij link, aby przejść do wybranego miejsca
Ta treść została automatycznie przetłumaczona z ukraińskiego.
Jeśli pracujesz z Rails i musisz uniknąć jednoczesnej zmiany jednego rekordu przez kilka procesów, warto zwrócić uwagę na mechanizm blokowania rekordów w bazie danych. Jednym z najpewniejszych sposobów na to jest pessimistic locking.

Co to jest pessimistic lock?

Pessimistic lock (pesymistyczne blokowanie) oznacza, że rekord w bazie danych jest fizycznie blokowany dla zmian z innych wątków lub procesów, dopóki bieżąca operacja się nie zakończy. To znaczy, że jeśli jeden proces uzyskał blokadę na rekord, inne muszą czekać, aż ją zwolni.
W ActiveRecord pesymistyczne blokowanie realizowane jest przez metodę lock, która dodaje SELECT ... FOR UPDATE, co utrzymuje blokadę do końca transakcji.

Użycie w Rails

Oto prosty przykład użycia lock w Rails:
ActiveRecord::Base.transaction do
  order = Order.lock.find(order_id)
  order.status = "processed"
  order.save!
end
W tym przypadku, jeśli inny proces spróbuje uzyskać Order z tym samym order_id, będzie musiał czekać, aż bieżący proces zakończy transakcję.

Po co to potrzebne?

Wyobraźmy sobie, że przetwarzamy zamówienia. Kiedy użytkownik naciska przycisk "Zapłać", musimy zmniejszyć ilość towaru na magazynie. Jeśli kilka osób jednocześnie próbuje kupić ostatnią sztukę towaru, bez blokady możliwy jest wyścig warunków:
  1. Proces 1 odczytuje ilość towaru (1 sztuka).
  2. Proces 2 odczytuje tę samą ilość (1 sztuka).
  3. Oba procesy próbują zapisać nową wartość (0 sztuk).
  4. Jeden z procesów traci aktualizację drugiego.
Jeśli jednak użyjemy lock, drugi proces będzie musiał poczekać na zakończenie pierwszego, a dopiero potem podejmować decyzję, co robić.

Alternatywy dla pessimistic lock

Pessimistic locking nie zawsze jest najlepszym wyborem, ponieważ może blokować inne procesy, spowalniając działanie aplikacji. Czasami lepiej użyć:
  1. Optimistic Locking — sprawdza, czy rekord zmienił się między odczytem a zapisem.
  2. Operacje atomowe — używa UPDATE ... WHERE lub increment! bez odczytywania wartości w Ruby.
  3. Podejście oparte na kolejce — rozdziela aktualizacje przez kolejkę (Sidekiq, RabbitMQ).

Optimistic Locking w Rails

Optimistic locking działa przez kolumnę lock_version. Jeśli dwa procesy odczytują rekord, to przy próbie zapisania zmian system sprawdza, czy rekord nie zmienił się w międzyczasie:
class Order < ApplicationRecord
  attr_accessor :lock_version
end
Wtedy, jeśli jeden proces wprowadzi zmiany, a inny spróbuje zapisać przestarzałą wersję, otrzyma ActiveRecord::StaleObjectError.
Prościej mówiąc:
  • Pessimistic locking blokuje rekord, aby uniknąć konfliktów.
  • Optimistic locking pozwala pracować bez blokady, ale wymaga obsługi konfliktów.
  • Operacje atomowe zmniejszają ryzyko wyścigu warunków bez blokad.
Wybieraj odpowiednie podejście w zależności od zadania. Jeśli krytycznie uniknąć konfliktów za wszelką cenę — użyj lock. Jeśli ważna jest wydajność i można pozwolić na konflikty — lepiej lock_version lub aktualizacje atomowe.

🔥 Więcej postów

Wszystkie wpisy
Co to jest CFB (Cipher Feedback)?
Programowanie (Програмування)21 mar '25 16:53

Co to jest CFB (Cipher Feedback)?

CFB (Cipher Feedback) – to tryb szyfrowania, w którym każdy blok zależy od poprzedniego, co zapew...

Co to jest XOR i jak to działa?
Programowanie (Програмування)21 mar '25 17:05

Co to jest XOR i jak to działa?

XOR (wykluczające LUB) – to operacja logiczna, która jest używana w szyfrowaniu, zmianie bitów i ...