Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Różnica między LockModeType Jpa

Najpierw rozróżniłbym blokady optymistyczne i pesymistyczne, ponieważ różnią się one mechanizmem leżącym u ich podstaw.

Blokowanie optymistyczne jest w pełni kontrolowane przez JPA i wymaga jedynie dodatkowej kolumny wersji w tabelach DB. Jest całkowicie niezależny od bazowego silnika bazy danych używanego do przechowywania danych relacyjnych.

Z drugiej strony, blokowanie pesymistyczne wykorzystuje mechanizm blokowania zapewniany przez podstawową bazę danych do blokowania istniejących rekordów w tabelach. JPA musi wiedzieć, jak uruchomić te blokady, a niektóre bazy danych nie obsługują ich lub tylko częściowo.

Teraz do listy typów zamków:

  1. LockModeType.Optimistic
    • Jeśli jednostki określają pole wersji, jest to pole domyślne. W przypadku jednostek bez kolumny wersji użycie tego typu blokady nie gwarantuje działania w żadnej implementacji JPA. Ten tryb jest zwykle ignorowany, jak określono w ObjectDB. Moim zdaniem istnieje tylko po to, aby można było dynamicznie obliczyć tryb blokady i przekazać go dalej, nawet jeśli blokada byłaby ostatecznie OPTYMISTYCZNA. Nie jest to jednak bardzo prawdopodobny przypadek użycia, ale zawsze dobrym projektem API jest zapewnienie opcji odwoływania się nawet do wartości domyślnej.
  • Przykład:

       `LockModeType lockMode = resolveLockMode();
     A a = em.find(A.class, 1, lockMode);`
    
  1. LockModeType.OPTIMISTIC_FORCE_INCREMENT
  • Jest to rzadko używana opcja. Ale może być rozsądne, jeśli chcesz zablokować odwoływanie się do tej encji przez inną encję. Innymi słowy, chcesz zablokować pracę z encją, nawet jeśli nie jest ona modyfikowana, ale inne encje mogą być modyfikowane w odniesieniu do tej encji.
  • Przykład:Mamy księgę i półkę jednostki. Możliwe jest dodanie książki do półki, ale książka nie ma żadnego odniesienia do swojej półki. Rozsądne jest zablokowanie czynności przenoszenia książki na półkę, aby książka nie znalazła się na innej półce (z powodu innej transakcji) przed zakończeniem tej transakcji. Aby zablokować tę akcję, nie wystarczy zablokować bieżącą jednostkę półki książki, ponieważ książka nie musi jeszcze znajdować się na półce. Nie ma również sensu blokowanie wszystkich docelowych półek na książki, ponieważ prawdopodobnie byłyby różne w różnych transakcjach. Jedyną rzeczą, która ma sens, jest zablokowanie samej encji książki, nawet jeśli w naszym przypadku nie zostanie ona zmieniona (nie ma odniesienia do swojej półki z książkami).
  1. LockModeType.PESSIMISTIC_READ
  • ten tryb jest podobny do LockModeType.PESSIMISTIC_WRITE , ale różni się jednym:dopóki blokada zapisu nie zostanie nałożona na tę samą encję przez jakąś transakcję, nie powinna blokować odczytu encji. Umożliwia również blokowanie innych transakcji za pomocą LockModeType.PESSIMISTIC_READ . Różnice między blokadami WRITE i READ są dobrze wyjaśnione tutaj (ObjectDB) i tutaj (OpenJPA). Jeśli jednostka jest już zablokowana przez inną transakcję, każda próba jej zablokowania spowoduje zgłoszenie wyjątku. To zachowanie można zmodyfikować tak, aby czekało przez pewien czas na zwolnienie blokady przed zgłoszeniem wyjątku i wycofaniem transakcji. W tym celu określ javax.persistence.lock.timeout wskazówka z liczbą milisekund oczekiwania przed zgłoszeniem wyjątku. Można to zrobić na wiele sposobów na wielu poziomach, jak opisano w samouczku Java EE.
  1. LockModeType.PESSIMISTIC_WRITE
  • to silniejsza wersja LockModeType.PESSIMISTIC_READ . Kiedy WRITE blokada jest na miejscu, JPA z pomocą bazy danych uniemożliwi jakiejkolwiek innej transakcji odczytanie encji, a nie tylko zapis jak w przypadku READ zablokuj.
  • Sposób, w jaki jest to zaimplementowane w dostawcy JPA we współpracy z bazową bazą danych, nie jest określony. W twoim przypadku z Oracle powiedziałbym, że Oracle nie zapewnia czegoś zbliżonego do READ Zamek. SELECT...FOR UPDATE jest raczej WRITE Zamek. Może to być błąd w hibernacji lub po prostu decyzja, że ​​zamiast zaimplementować niestandardowe "miękkie" READ blokada, „trudniejsze” WRITE zamiast tego używany jest zamek. To w większości nie narusza spójności, ale nie utrzymuje wszystkich reguł z READ zamki. Możesz uruchomić kilka prostych testów za pomocą READ blokady i długotrwałe transakcje, aby dowiedzieć się, czy więcej transakcji może uzyskać READ blokady na tej samej jednostce. Powinno to być możliwe, ale nie w przypadku WRITE zamki.
  1. LockModeType.PESSIMISTIC_FORCE_INCREMENT
  • to kolejny rzadko używany tryb blokady. Jest to jednak opcja, w której musisz połączyć PESSIMISTIC i OPTIMISTIC mechanizmy. Używanie zwykłego PESSIMISTIC_WRITE nie powiedzie się w następującym scenariuszu:
    1. transakcja A używa optymistycznego blokowania i odczytuje encję E
    2. transakcja B uzyskuje blokadę WRITE na jednostce E
    3. transakcja B zatwierdza i zwalnia blokadę E
    4. transakcja A aktualizuje E i zatwierdza
  • w kroku 4, jeśli kolumna wersji nie jest zwiększana przez transakcję B, nic nie stoi na przeszkodzie, aby A nadpisał zmiany B. Tryb blokady LockModeType.PESSIMISTIC_FORCE_INCREMENT zmusi transakcję B do aktualizacji numeru wersji i spowoduje niepowodzenie transakcji A z OptimisticLockException , mimo że B używał pesymistycznego blokowania.
  1. LockModeType.BRAK
  • jest to ustawienie domyślne, jeśli jednostki nie udostępniają pola wersji. Oznacza to, że żadne blokowanie nie jest włączone, konflikty będą rozwiązywane na zasadzie najlepszych starań i nie zostaną wykryte. To jedyny tryb blokady dozwolony poza transakcją



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Liczba piątków między dwiema datami

  2. Powrót z Open World 2013

  3. Poznaj historię zapytań SQL

  4. Problem z hibernacją z wyzwalaczem Oracle do generowania identyfikatora z sekwencji

  5. Wybierz z tabeli, znając tylko datę bez czasu (ORACLE)