Cała oryginalna treść jest tworzona po ukraińsku. Nie wszystkie treści zostały jeszcze przetłumaczone. Niektóre posty mogą być dostępne tylko po ukraińsku.Dowiedz się więcej

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

Okładka posta: Pessimistic Lock w Rails: co to jest i kiedy stosować. Jakie są alternatywy?
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.

Ten post nie ma jeszcze żadnych dodatków od autora.

Struktura Promise (JavaScript) i jak z tym pracować
18 lut 14:33

Struktura Promise (JavaScript) i jak z tym pracować

meme code
meme code@memecode
Czym jest memoizacja (przykłady Ruby i Ruby on Rails)?
20 lut 18:16

Czym jest memoizacja (przykłady Ruby i Ruby on Rails)?

meme code
meme code@memecode
Czym jest debounce w JavaScript i dlaczego jest to ważne?
21 mar 16:39

Czym jest debounce w JavaScript i dlaczego jest to ważne?

meme code
meme code@memecode
Co to jest CFB (Cipher Feedback)?
21 mar 16:53

Co to jest CFB (Cipher Feedback)?

meme code
meme code@memecode
Co to jest XOR i jak to działa?
21 mar 17:05

Co to jest XOR i jak to działa?

meme code
meme code@memecode
Programowanie wbudowane: co to jest i od czego zacząć
24 mar 16:48

Programowanie wbudowane: co to jest i od czego zacząć

meme code
meme code@memecode
Dlaczego PostgreSQL pomija ID podczas zapisywania nowych rekordów? (Heroku)
31 mar 19:13

Dlaczego PostgreSQL pomija ID podczas zapisywania nowych rekordów? (Heroku)

meme code
meme code@memecode
[Codecov] Jaka jest różnica między pokryciem patch a pokryciem projektu?
9 kwi 16:03

[Codecov] Jaka jest różnica między pokryciem patch a pokryciem projektu?

meme code
meme code@memecode
Jak kursy Scratch pomagają dzieciom rozwijać umiejętności miękkie?
11 kwi 18:24

Jak kursy Scratch pomagają dzieciom rozwijać umiejętności miękkie?

meme code
meme code@memecode
24 kwi 20:17

Naprawiamy minikube "Próbujesz uruchomić binarkę amd64 na systemie M1."

meme code
meme code@memecode
24 kwi 20:55

Instalujemy minikube na Macu z M1 (rezygnujemy z qemu, uruchamiamy na dockerze)

meme code
meme code@memecode
Gdzie znaleźć starszą wersję Google Chrome i ją pobrać? Na przykładzie starego Maca
25 kwi 23:02

Gdzie znaleźć starszą wersję Google Chrome i ją pobrać? Na przykładzie starego Maca

meme code
meme code@memecode