Są to dwa wstawiane komentarze z tym samym identyfikatorem content_id. Samo wstawienie komentarza zdejmuje blokadę SHARE w wierszu treści, aby zatrzymać kolejną transakcję, usuwającą ten wiersz, dopóki pierwsza transakcja nie zostanie zakończona.
Jednak wyzwalacz następnie przechodzi do uaktualnienia blokady do EXCLUSIVE, co może zostać zablokowane przez równoczesną transakcję wykonującą ten sam proces. Rozważ następującą sekwencję wydarzeń:
Txn 2754 Txn 2053
Insert Comment
Insert Comment
Lock Content#935967 SHARE
(performed by fkey)
Lock Content#935967 SHARE
(performed by fkey)
Trigger
Lock Content#935967 EXCLUSIVE
(blocks on 2053's share lock)
Trigger
Lock Content#935967 EXCLUSIVE
(blocks on 2754's share lock)
Więc – impas.
Jednym z rozwiązań jest natychmiast zablokuj na wyłączność wiersz treści przed wstawienie komentarza. tj.
SELECT 1 FROM content WHERE content.id = 935967 FOR UPDATE
INSERT INTO comment(.....)
Innym rozwiązaniem jest po prostu całkowite uniknięcie tego wzorca „liczby w pamięci podręcznej”, z wyjątkiem sytuacji, w których można udowodnić, że jest to konieczne dla wydajności. Jeśli tak, rozważ umieszczenie licznika w pamięci podręcznej w innym miejscu niż tabela zawartości, np. dedykowany stolik na ladę. Zmniejszy to również ruch związany z aktualizacją do tabeli treści za każdym razem, gdy zostanie dodany komentarz. A może po prostu ponownie wybierz licznik i użyj memcached w aplikacji. Nie można obejść się bez faktu, że gdziekolwiek przechowujesz tę liczbę w pamięci podręcznej, będzie ona punktem dławienia, należy ją bezpiecznie zaktualizować.