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

Czy SELECT ... FOR UPDATE powinien zawsze zawierać ORDER BY?

Twój przykład w twoim pytaniu pokazuje, że kolejność blokowania zależy od metody dostępu. Ta ścieżka dostępu nie jest bezpośrednio określana przez klauzulę ORDER BY zapytania, istnieje wiele czynników, które mogą wpływać na tę ścieżkę dostępu. Dlatego nie można zapobiec zakleszczeniu poprzez dodanie ORDER BY, ponieważ nadal mogą istnieć dwie różne ścieżki dostępu. W rzeczywistości, uruchamiając Twój przypadek testowy z kolejnością według i zmieniając parametry sesji, udało mi się spowodować, że dwie sesje uruchomią ORA-60 z tym samym zapytaniem.

Jeśli zaangażowane sesje nie mają innych oczekujących blokad, blokowanie wierszy w tej samej kolejności we wszystkich sesjach zapobiegnie zakleszczeniu się, ale jak niezawodnie wymusić tę kolejność? Zauważ, że i tak zapobiegłoby to tylko temu szczególnemu przypadkowi impasu. Nadal możesz napotkać impas z wieloma zapytaniami w każdej sesji lub różnymi planami.

W praktyce ten przypadek jest naprawdę wyjątkowy i i tak nie powinien zdarzać się często:jeśli martwisz się impasami, nadal uważam, że istnieją prostsze metody, aby im zapobiec.

Najłatwiejszym sposobem uniknięcia zakleszczenia jest użycie opcji FOR UPDATE NOWAIT lub FOR UPDATE WAIT X (chociaż WAIT X może nadal wywołać zakleszczenie z wartościami X lepszymi od mechanizmu wykrywania zakleszczeń, obecnie uważam, że 3 sekundy od 11g -- dzięki @APC do korekty).

Innymi słowy, obie transakcje powinny zapytać:daj mi te wiersze i zablokuj je, ale jeśli inny użytkownik ma już blokadę, zwróć błąd zamiast czekać w nieskończoność. To nieskończone oczekiwanie powoduje impas.

W praktyce powiedziałbym, że większość aplikacji z rzeczywistymi użytkownikami wolałaby otrzymać błąd natychmiast, niż kazać transakcję czekać w nieskończoność na zakończenie kolejnej transakcji. Rozważę FOR UPDATE bez NOWAIT tylko dla niekrytycznych zadań wsadowych.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. php losowe dane mysql

  2. 10 najciekawszych faktów i wskazówek dotyczących MySQL

  3. H2 - Błąd dostępu do tabeli połączonej za pomocą instrukcji SQL SELECT * FROM null T

  4. Jak używać wyrażenia regularnego w zapytaniu django

  5. Mysql:Zamów według polubienia?