sql >> Database >  >> RDS >> Oracle

Verschil tussen LockModeType Jpa

Ik zou eerst onderscheid maken tussen optimistische en pessimistische sloten, omdat ze verschillen in hun onderliggende mechanisme.

Optimistische vergrendeling wordt volledig beheerd door JPA en vereist alleen een extra versiekolom in DB-tabellen. Het is volledig onafhankelijk van de onderliggende DB-engine die wordt gebruikt om relationele gegevens op te slaan.

Aan de andere kant gebruikt pessimistische vergrendeling een vergrendelingsmechanisme dat wordt geleverd door de onderliggende database om bestaande records in tabellen te vergrendelen. JPA moet weten hoe deze vergrendelingen te activeren en sommige databases ondersteunen ze niet of slechts gedeeltelijk.

Nu naar de lijst met slottypes:

  1. LockModeType.Optimistic
    • Als entiteiten een versieveld specificeren, is dit de standaardinstelling. Voor entiteiten zonder een versiekolom kan het gebruik van dit type vergrendeling niet gegarandeerd werken op een JPA-implementatie. Deze modus wordt meestal genegeerd, zoals aangegeven door ObjectDB. Naar mijn mening bestaat het alleen zodat je de vergrendelingsmodus dynamisch kunt berekenen en verder kunt doorgeven, zelfs als de vergrendeling uiteindelijk OPTIMISTISCH zou zijn. Niet erg waarschijnlijk gebruik echter, maar het is altijd een goed API-ontwerp om een ​​optie te bieden om zelfs naar de standaardwaarde te verwijzen.
  • Voorbeeld:

       `LockModeType lockMode = resolveLockMode();
     A a = em.find(A.class, 1, lockMode);`
    
  1. LockModeType.OPTIMISTIC_FORCE_INCREMENT
  • Dit is een zelden gebruikte optie. Maar het kan redelijk zijn als u de verwijzing naar deze entiteit door een andere entiteit wilt vergrendelen. Met andere woorden, u wilt het werken met een entiteit vergrendelen, zelfs als deze niet is gewijzigd, maar andere entiteiten kunnen worden gewijzigd met betrekking tot deze entiteit.
  • Voorbeeld:we hebben entiteit Book and Shelf. Het is mogelijk om Boek aan plank toe te voegen, maar boek heeft geen verwijzing naar de plank. Het is redelijk om de actie van het verplaatsen van een boek naar een plank te vergrendelen, zodat een boek niet voor het einde van deze transactie op een andere plank belandt (vanwege een andere transactie). Om deze actie te vergrendelen, is het niet voldoende om de huidige boekenplankentiteit te vergrendelen, omdat het boek nog niet op een plank hoeft te staan. Het heeft ook geen zin om alle doelboekenplanken te vergrendelen, omdat ze bij verschillende transacties waarschijnlijk anders zouden zijn. Het enige dat logisch is, is om de boekentiteit zelf te vergrendelen, zelfs als deze in ons geval niet wordt gewijzigd (het bevat geen verwijzing naar zijn boekenplank).
  1. LockModeType.PESSIMISTIC_READ
  • deze modus is vergelijkbaar met LockModeType.PESSIMISTIC_WRITE , maar in één ding anders:totdat de schrijfvergrendeling door een transactie op dezelfde entiteit is geplaatst, mag het het lezen van de entiteit niet blokkeren. Het staat ook toe dat andere transacties worden vergrendeld met LockModeType.PESSIMISTIC_READ . De verschillen tussen WRITE- en READ-locks worden hier (ObjectDB) en hier (OpenJPA) goed uitgelegd. Als een entiteit al is vergrendeld door een andere transactie, zal elke poging om deze te vergrendelen een uitzondering veroorzaken. Dit gedrag kan worden gewijzigd om enige tijd te wachten totdat de vergrendeling is vrijgegeven voordat een uitzondering wordt gegenereerd en de transactie wordt teruggedraaid. Om dat te doen, specificeert u de javax.persistence.lock.timeout hint met het aantal milliseconden dat moet worden gewacht voordat de uitzondering wordt gegenereerd. Er zijn meerdere manieren om dit op meerdere niveaus te doen, zoals beschreven in de Java EE-zelfstudie.
  1. LockModeType.PESSIMISTIC_WRITE
  • dit is een sterkere versie van LockModeType.PESSIMISTIC_READ . Wanneer WRITE slot op zijn plaats is, zal JPA met behulp van de database voorkomen dat elke andere transactie de entiteit leest, niet alleen om te schrijven zoals met READ slot.
  • De manier waarop dit wordt geïmplementeerd in een JPA-provider in samenwerking met onderliggende DB is niet voorgeschreven. In uw geval met Oracle zou ik zeggen dat Oracle niet iets biedt dat in de buurt komt van een READ slot. SELECT...FOR UPDATE is eigenlijk eerder een WRITE slot. Het kan een bug zijn in de slaapstand of gewoon een beslissing die, in plaats van aangepaste "zachtere" READ te implementeren, slot, de "hardere" WRITE slot wordt in plaats daarvan gebruikt. Dit verbreekt meestal de consistentie niet, maar bevat niet alle regels met READ sloten. U kunt enkele eenvoudige tests uitvoeren met READ locks en langlopende transacties om erachter te komen of meer transacties READ . kunnen verwerven sloten op dezelfde entiteit. Dit zou mogelijk moeten zijn, maar niet met WRITE sloten.
  1. LockModeType.PESSIMISTIC_FORCE_INCREMENT
  • dit is een andere zelden gebruikte vergrendelingsmodus. Het is echter een optie waarbij u PESSIMISTIC . moet combineren en OPTIMISTIC mechanismen. Gebruik gewoon PESSIMISTIC_WRITE zou mislukken in het volgende scenario:
    1. transactie A gebruikt optimistische vergrendeling en leest entiteit E
    2. transactie B verwerft WRITE lock op entiteit E
    3. transactie B begaat en geeft slot van E vrij
    4. transactie A werkt E bij en verbindt zich
  • in stap 4, als de versiekolom niet wordt verhoogd door transactie B, verhindert niets A de wijzigingen van B te overschrijven. Vergrendelmodus LockModeType.PESSIMISTIC_FORCE_INCREMENT dwingt transactie B om het versienummer bij te werken en zorgt ervoor dat transactie A mislukt met OptimisticLockException , ook al gebruikte B pessimistische vergrendeling.
  1. LockModeType.NONE
  • dit is de standaardinstelling als entiteiten geen versieveld bieden. Dit betekent dat er geen vergrendeling is ingeschakeld. Conflicten worden naar beste vermogen opgelost en niet gedetecteerd. Dit is de enige vergrendelingsmodus die buiten een transactie is toegestaan



  1. PHP laadt php_pgsql.dll niet op Windows

  2. Is er een manier om een ​​gebruikersvriendelijke foutmelding te geven bij overtreding van de beperking?

  3. LINQ to SQL Take w/o Skip Veroorzaakt meerdere SQL-statements

  4. SQL Server-equivalent van de functie substring_index in MySQL