W moim kodzie Railsowym muszę potwierdzić, że akcja jest dozwolona tylko wtedy, gdy jest więcej niż 1 z określonego rekordu. Z tego powodu muszę zablokować aktualizacje, a następnie wykonać odczyt. Mój kod szyn wygląda następująco:Szyny + MySQL + Transakcje + Blokowanie, w jaki sposób zapobiec odblokowaniu transakcji przez odblokowanie tabeli?
PaymentProfile.transaction do
profiles = PaymentProfile.lock("LOCK IN SHARE MODE").where(user_id: xxx)
if profiles.count > 1
#allow
else
#do not allow
end
end
Teoretycznie działa to dobrze i prawidłowo blokuje rzędy. JEDNAKŻE, jeśli kolejne żądanie przechodzi przez tę samą ścieżkę kodową, otwarcie transakcji usuwa blokadę, którą wyjąłem w innym procesie, tym samym pokonując cel blokady.
Od docs MySQL:
Beginning a transaction also causes table locks acquired with LOCK TABLES to be released, as though you had executed UNLOCK TABLES. Beginning a transaction does not release a global read lock acquired with FLUSH TABLES WITH READ LOCK.