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

Hibernacja:Zakleszczenie podczas próby uzyskania blokady

Ponieważ zakleszczenia zdarzają się tak często, wygląda na to, że niektóre wątki aplikacji utrzymują blokady przez dłuższy czas.

Każdy wątek w aplikacji będzie korzystał z własnego połączenia/połączeń z bazą danych podczas uzyskiwania dostępu do bazy danych, więc z punktu widzenia bazy danych dwa wątki to dwa różne klienty, które konkurują o blokady bazy danych.

Jeśli wątek utrzymuje blokady przez dłuższy czas i nabywa je w określonej kolejności, a drugi wątek nadchodzi, uzyskując te same blokady, ale w innej kolejności, nastąpi zakleszczenie (patrz tutaj aby uzyskać szczegółowe informacje na temat tej częstej przyczyny zakleszczenia).

W operacjach odczytu występują również zakleszczenia, co oznacza, że ​​niektóre wątki również uzyskują blokady odczytu. Dzieje się tak, jeśli wątki wykonują transakcje w REPEATABLE_READ poziom izolacji lub SERIALIZABLE .

Aby rozwiązać ten problem, spróbuj wyszukać zastosowania Isolation.REPEATABLE_READ i Isolation.SERIALIZABLE w projekcie, aby sprawdzić, czy jest on używany.

Alternatywnie użyj domyślnego READ_COMMITTED poziom izolacji i adnotuj encje za pomocą @Version , do obsługi współbieżności przy użyciu optymistycznego blokowania zamiast tego.

Spróbuj także zidentyfikować długotrwałe transakcje, co zdarza się czasami, gdy @Transactional jest umieszczony w niewłaściwym miejscu i zawija na przykład przetwarzanie całego pliku w przykładzie przetwarzania wsadowego, zamiast wykonywać transakcje linia po linii.

Jest to konfiguracja log4j do rejestrowania tworzenia/usuwania menedżerów encji i rozpoczynania/zatwierdzania/wycofywania transakcji:

   <!-- spring entity manager and transactions -->
<logger name="org.springframework.orm.jpa" additivity ="false">
    <level value="debug" />
    <appender-ref ref="ConsoleAppender" />
</logger >
<logger name="org.springframework.transaction" additivity ="false">
    <level value="debug" />
    <appender-ref ref="ConsoleAppender" />
</logger >
  1. Czy mogę w jakiś sposób wykonać zapytanie aktualizacyjne (zarówno JPA, jak i natywne) bez konieczności blokowania tabeli przez @Transactional?

Zapytania aktualizacyjne są możliwe za pośrednictwem zapytań natywnych lub JPQL .

  1. Czy mogę w jakiś sposób wejść do sesji bez użycia @Transactional? Na przykład zaplanowany wątek próbuje odczytać pole Lazy na Entity zwraca LazyInitializationException — brak sesji, jeśli metoda nie jest oznaczona adnotacją @Transactional

W metodach bez @Transactional , zapytania będą wykonywane we własnym menedżerze encji i zwracają tylko odłączone encje, ponieważ sesja jest zamykana natychmiast po uruchomieniu zapytania.

więc leniwe wyjątki inicjalizacji w metodach bez @Transactional jest normalne. Możesz ustawić je na @Transactional(readOnly=true) również.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Wyrażenie regularne str_replace

  2. mysql_query() oczekuje, że parametr 2 będzie zasobem, łańcuch podany w

  3. Wysyłaj dane z Androida na serwer przez JSON

  4. mysqli_stmt::bind_param():Liczba elementów w ciągu definicji typu nie odpowiada liczbie zmiennych wiązania

  5. Napraw „BŁĄD 1054 (42S22):Nieznana kolumna „…” w „klauzula zamówienia” podczas używania UNION w MySQL