sql >> Databasteknik >  >> RDS >> Oracle

Skillnaden mellan LockModeType Jpa

Jag skulle först skilja på optimistiska och pessimistiska lås, eftersom de är olika i sin underliggande mekanism.

Optimistisk låsning kontrolleras helt av JPA och kräver endast ytterligare versionskolumn i DB-tabeller. Den är helt oberoende av underliggande DB-motor som används för att lagra relationsdata.

Å andra sidan använder pessimistisk låsning låsmekanism som tillhandahålls av den underliggande databasen för att låsa befintliga poster i tabeller. JPA måste veta hur man utlöser dessa lås och vissa databaser stöder dem inte eller bara delvis.

Nu till listan över låstyper:

  1. LockModeType.Optimistic
    • Om enheter anger ett versionsfält är detta standard. För enheter utan en versionskolumn är det inte garanterat att denna typ av lås fungerar på någon JPA-implementering. Detta läge ignoreras vanligtvis enligt ObjectDB. Enligt min mening existerar det bara så att du kan beräkna låsläget dynamiskt och skicka det vidare även om låset skulle vara OPTIMISTISKt i slutändan. Inte särskilt troligt användningsfall dock, men det är alltid bra API-design för att tillhandahålla en möjlighet att referera även till standardvärdet.
  • Exempel:

       `LockModeType lockMode = resolveLockMode();
     A a = em.find(A.class, 1, lockMode);`
    
  1. LockModeType.OPTIMISTIC_FORCE_INCREMENT
  • Detta är ett sällan använt alternativ. Men det kan vara rimligt om du vill låsa hänvisning till denna enhet av en annan enhet. Med andra ord vill du låsa att arbeta med en entitet även om den inte är modifierad, men andra entiteter kan ändras i förhållande till denna entitet.
  • Exempel:Vi har entitetsbok och -hylla. Det är möjligt att lägga till bok i hyllan, men boken har ingen referens till sin hylla. Det är rimligt att låsa handlingen att flytta en bok till en hylla, så att en bok inte hamnar i en annan hylla (på grund av en annan transaktion) innan denna transaktion är slut. För att låsa den här åtgärden räcker det inte att låsa den aktuella bokhyllan, eftersom boken inte behöver finnas på en hylla ännu. Det är inte heller meningsfullt att låsa alla målbokhyllor, eftersom de förmodligen skulle vara olika i olika transaktioner. Det enda som är vettigt är att låsa själva bokentiteten, även om den i vårt fall inte ändras (den har ingen hänvisning till sin bokhylla).
  1. LockModeType.PESSIMISTIC_READ
  • det här läget liknar LockModeType.PESSIMISTIC_WRITE , men olika i en sak:tills skrivlås är på plats på samma enhet av någon transaktion, bör det inte blockera läsning av enheten. Det tillåter också att andra transaktioner låses med LockModeType.PESSIMISTIC_READ . Skillnaderna mellan WRITE- och READ-lås förklaras väl här (ObjectDB) och här (OpenJPA). Om en enhet redan är låst av en annan transaktion kommer varje försök att låsa den att leda till ett undantag. Det här beteendet kan ändras till att vänta en tid på att låset släpps innan du kastar ett undantag och återställer transaktionen. För att göra det, ange javax.persistence.lock.timeout antyda antalet millisekunder att vänta innan du kastar undantaget. Det finns flera sätt att göra detta på flera nivåer, som beskrivs i Java EE-handledningen.
  1. LockModeType.PESSIMISTIC_WRITE
  • det här är en starkare version av LockModeType.PESSIMISTIC_READ . När WRITE låset är på plats, kommer JPA med hjälp av databasen att förhindra någon annan transaktion för att läsa enheten, inte bara att skriva som med READ lås.
  • Sättet hur detta implementeras i en JPA-leverantör i samarbete med underliggande DB är inte föreskrivet. I ditt fall med Oracle skulle jag säga att Oracle inte tillhandahåller något i närheten av en READ låsa. SELECT...FOR UPDATE är egentligen snarare en WRITE låsa. Det kan vara en bugg i viloläge eller bara ett beslut som istället för att implementera anpassade "mjukare" READ lås, desto "hårdare" WRITE lås används istället. Detta bryter för det mesta inte konsistensen, men håller inte alla regler med READ lås. Du kan köra några enkla tester med READ lås och långvariga transaktioner för att ta reda på om fler transaktioner kan få READ låser på samma enhet. Detta borde vara möjligt, men inte med WRITE lås.
  1. LockModeType.PESSIMISTIC_FORCE_INCREMENT
  • det här är ett annat sällan använt låsläge. Det är dock ett alternativ där du behöver kombinera PESSIMISTIC och OPTIMISTIC mekanismer. Använder vanlig PESSIMISTIC_WRITE skulle misslyckas i följande scenario:
    1. Transaktion A använder optimistisk låsning och läser entitet E
    2. transaktion B förvärvar WRITE-lås på entitet E
    3. transaktion B begår och släpper låset för E
    4. Transaktion A uppdaterar E och förbinder sig
  • i steg 4, om versionskolumnen inte ökas med transaktion B, hindrar ingenting A från att skriva över ändringar av B. Låsläge LockModeType.PESSIMISTIC_FORCE_INCREMENT kommer att tvinga transaktion B att uppdatera versionsnummer och gör att transaktion A misslyckas med OptimisticLockException , även om B använde pessimistisk låsning.
  1. LockModeType.NONE
  • detta är standard om enheter inte tillhandahåller ett versionsfält. Det betyder att ingen låsning är aktiverad konflikter kommer att lösas på bästa sätt och kommer inte att upptäckas. Detta är det enda låsläget som är tillåtet utanför en transaktion



  1. PostgreSQL - hämta raden som har maxvärdet för en kolumn

  2. Följ med oss ​​för en introduktion till åtkomst med SQL Server

  3. Så här fixar du "Ett korrelationsnamn måste anges för bulkraduppsättningen i from-satsen." i SQL Server

  4. varför PG::UniqueViolation:FEL:dubblettnyckelvärde bryter mot unik begränsning?