Dla Spring Data w wersji 1.6 lub nowszej
@Lock jest obsługiwany w metodach CRUD od wersji 1.6 Spring Data JPA (w rzeczywistości istnieje już kamień milowy
do dyspozycji). Zobacz ten bilet
po więcej szczegółów.
W tej wersji po prostu deklarujesz, co następuje:
interface WidgetRepository extends Repository<Widget, Long> {
@Lock(LockModeType.PESSIMISTIC_WRITE)
Widget findOne(Long id);
}
Spowoduje to, że część implementacji CRUD serwera proxy repozytorium zapasowego zastosuje skonfigurowany LockModeType do find(…) wywołaj EntityManager .
Z drugiej strony
Dla poprzedniej wersji Spring Data 1.6
Pesymistyczne @Lock Spring Data adnotacje dotyczą tylko (jak wskazałeś) zapytań. Nie znam adnotacji, które mogłyby wpłynąć na całą transakcję. Możesz utworzyć findByOnePessimistic metoda, która wywołuje findByOne z pesymistyczną blokadą lub możesz zmienić findByOne aby zawsze uzyskać pesymistyczny zamek.
Jeśli chciałbyś wdrożyć własne rozwiązanie, prawdopodobnie mógłbyś. Pod maską @Lock adnotacja jest przetwarzana przez LockModePopulatingMethodIntercceptor który wykonuje następujące czynności:
TransactionSynchronizationManager.bindResource(method, lockMode == null ? NULL : lockMode);
Możesz stworzyć statycznego menedżera blokad, który miał ThreadLocal<LockMode> zmienna członkowska, a następnie ma aspekt owinięty wokół każdej metody w każdym repozytorium, która wywołała bindResource z trybem blokady ustawionym w ThreadLocal. Umożliwiłoby to ustawienie trybu blokady na podstawie wątku. Następnie możesz stworzyć swój własny @MethodLockMode adnotacja, która zawijałaby metodę w aspekt, który ustawia tryb blokady specyficzny dla wątku przed uruchomieniem metody i czyści go po uruchomieniu metody.
Link do zasobów:
- Jak włączyć LockModeType.PESSIMISTIC_WRITE podczas wyszukiwania jednostek za pomocą Spring Data JPA?
- Jak dodać niestandardowe metoda do Spring Data JPA
- Limit czasu blokady pesymistycznych danych wiosennych z Postgresem
- interfejs API zapytań JPA
Różne przykłady pesymistycznego limitu czasu blokady
Ustawianie pesymistycznej blokady
Obiekt encji można zablokować jawnie za pomocą metody lock:
em.lock(employee, LockModeType.PESSIMISTIC_WRITE);
Pierwszy argument to obiekt encji. Drugi argument to żądany tryb blokady.
TransactionRequiredException jest generowany, jeśli nie ma aktywnej transakcji po wywołaniu blokady, ponieważ jawne blokowanie wymaga aktywnej transakcji.
LockTimeoutException jest wyrzucany, jeśli żądana blokada pesymistyczna nie może zostać przyznana:
PESSIMISTIC_READżądanie blokady kończy się niepowodzeniem, jeśli inny użytkownik (reprezentowany przez inną instancję EntityManager) aktualnie posiadaPESSIMISTIC_WRITEzablokować ten obiekt bazy danych.PESSIMISTIC_WRITEżądanie blokady kończy się niepowodzeniem, jeśli inny użytkownik aktualnie posiada alboPESSIMISTIC_WRITEzamek lubPESSIMISTIC_READzablokuj ten obiekt bazy danych.
Ustawianie podpowiedzi do zapytania (zakresy)
Wskazówki dotyczące zapytań można ustawić w następujących zakresach (od globalnego do lokalnego):
Dla całej jednostki trwałości - przy użyciu persistence.xml właściwość:
<properties>
<property name="javax.persistence.query.timeout" value="3000"/>
</properties>
Dla EntityManagerFactory — przy użyciu createEntityManagerFacotory metoda:
Map<String,Object> properties = new HashMap();
properties.put("javax.persistence.query.timeout", 4000);
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("pu", properties);
Dla EntityManager - za pomocą createEntityManager metoda:
Map<String,Object> properties = new HashMap();
properties.put("javax.persistence.query.timeout", 5000);
EntityManager em = emf.createEntityManager(properties);
lub za pomocą metody setProperty:
em.setProperty("javax.persistence.query.timeout", 6000);
Dla named query definicja - za pomocą hints element:
@NamedQuery(name="Country.findAll", query="SELECT c FROM Country c",
hints={@QueryHint(name="javax.persistence.query.timeout", value="7000")})
Dla wykonania określonego zapytania - za pomocą setHint metoda (przed wykonaniem zapytania):
query.setHint("javax.persistence.query.timeout", 8000);