Mysql
 sql >> Baza danych >  >> RDS >> Mysql

W jaki sposób tabele innodb są blokowane podczas przetwarzania wyzwalacza ON INSERT?

Jeśli chodzi o problemy ze współbieżnością, masz 'łatwe' sposób, aby zapobiec problemom ze współbieżnością w drugiej metodzie, wewnątrz transakcji wykonaj wybór w wierszu artykułów (For update jest teraz niejawna). Żadne jednoczesne wstawianie tego samego artykułu nie będzie w stanie uzyskać tej samej blokady i będzie na Ciebie czekać.

Dzięki nowym domyślnym poziomom izolacji, nawet bez użycia poziomu serializacji w transakcji, nie zobaczysz żadnego równoczesnego wstawiania w tabeli głosowania do końca transakcji. Więc Twoja SUMA powinna pozostać spójna lub wyglądać na spójną . Ale jeśli równoczesna transakcja wstawi głos na ten sam artykuł i zatwierdzenie przed tobą (a ta druga nie widzi twojego wstawienia), ostatnia transakcja do zatwierdzenia nadpisze licznik i stracisz 1 głos. Więc wykonaj blokowanie wiersza w artykule, używając opcji wyboru przed (i oczywiście wykonuj swoją pracę w transakcji). Łatwo jest przetestować, otworzyć 2 interaktywne sesje na MySQL i rozpocząć transakcje za pomocą BEGIN.

Jeśli używasz wyzwalacza, domyślnie jesteś w transakcji. Ale myślę, że powinieneś wykonać również wybór w tabeli artykułów, aby utworzyć niejawną blokadę wiersza dla współbieżnych uruchomionych wyzwalaczy (trudniejsze do przetestowania).

  • Nie zapomnij o usuwaniu wyzwalaczy.
  • Nie zapomnij wyzwalaczy aktualizacji.
  • Jeśli nie używasz wyzwalaczy i kodu pozostającego, zachowaj ostrożność, każde zapytanie wstawiania/usuwania/aktualizowania głosów powinno blokować wiersz w odpowiednim artykule przed transakcją. Nie jest trudno o jednym zapomnieć.

Ostatni punkt:wykonaj trudniejsze transakcje, przed rozpoczęciem transakcji użyj:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

W ten sposób nie potrzebujesz blokad wierszy w artykułach, MySQL wykryje, że potencjalny zapis w tym samym wierszu ma miejsce i zablokuje inne transakcje do momentu zakończenia. Ale nie używaj czegoś, co obliczyłeś na podstawie poprzedniego żądania . Zapytanie o aktualizację będzie czekać na zwolnienie blokady w artykułach, gdy blokada zostanie zwolniona przez pierwszą transakcję COMMIT obliczanie SUM należy zrobić ponownie, aby policzyć. Zapytanie o aktualizację powinno więc zawierać SUM lub uzupełnij.

update articles set nb_votes=(SELECT count(*) from vote) where id=2; 

I tutaj zobaczysz, że MySQL jest sprytny, wykryto zakleszczenie, jeśli dwie transakcje próbują to zrobić, podczas gdy wstawianie zostało wykonane w tym samym czasie. Na poziomach serializacji nie znalazłem sposobu na uzyskanie nieprawidłowej wartości za pomocą :

   SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
   BEGIN;
       insert into vote (...
       update articles set nb_votes=(
         SELECT count(*) from vote where article_id=xx
       ) where id=XX;
    COMMIT;

Ale przygotuj się na zerwanie transakcji, którą musisz powtórzyć.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Czy mogę użyć przygotowanej instrukcji PDO do powiązania identyfikatora (nazwy tabeli lub pola) lub słowa kluczowego składni?

  2. Połącz MySQL z Pythonem 3.6

  3. Jak uniknąć błędów funkcje agregujące nie są dozwolone w WHERE

  4. Sortowanie w MySQL przy użyciu kolejności według klauzul

  5. Nie znaleziono klasy „mysqli_connect”