Pesszimista zárolás a JPA-ban

1. Áttekintés

Rengeteg olyan helyzet van, amikor adatokat akarunk lekérni egy adatbázisból. Néha le akarjuk zárni magunknak további feldolgozás céljából, hogy senki más ne szakítsa meg a tetteinket.

Két párhuzamosság-ellenőrzési mechanizmusra gondolhatunk, amelyek lehetővé teszik számunkra ezt: a megfelelő tranzakciós elszigetelési szint beállítását vagy a pillanatnyilag szükséges adatok zárolásának beállítását.

A tranzakciószigetelést az adatbázis-kapcsolatokhoz adjuk meg. Beállíthatjuk a zárolási adatok különböző mértékű megtartására.

Azonban, az izoláció szintjét a kapcsolat létrejötte után állítják be és ez a kapcsolat minden állítását érinti. Szerencsére használhatunk pesszimista zárolást, amely adatbázis-mechanizmusokat használ az adatok részletesebb kizárólagos hozzáférésének fenntartására.

Pesszimista zárat használhatunk annak biztosítására, hogy más tranzakciók ne módosítsák vagy töröljék a fenntartott adatokat.

Kétféle zárat tarthatunk fenn: egy exkluzív és egy megosztott zárat. Tudnánk olvasni, de nem írhatnánk be adatokat, ha valaki más megosztott zárat tart. A fenntartott adatok módosításához vagy törléséhez kizárólagos zárra van szükségünk.

Exkluzív zárakat szerezhetünk aKIVÁLASZTÁS… FRISSÍTÉSRE’Állítások.

2. Lezárási módok

A JPA specifikációja három pesszimista zárolási módot határoz meg, amelyeket megvitatunk:

  • PESSIMISTIC_READ - lehetővé teszi számunkra, hogy megosztott zárat szerezzünk, és megakadályozzuk az adatok frissítését vagy törlését
  • PESSIMISTIC_WRITE - lehetővé teszi számunkra, hogy kizárólagos zárat szerezzünk, és megakadályozzuk az adatok olvasását, frissítését vagy törlését
  • PESSIMISTIC_FORCE_INCREMENT - működik, mint PESSIMISTIC_WRITE és emellett növeli a verziószámú entitás verzióattribútumát

Mindegyikük a LockModeType osztályban, és lehetővé teszi a tranzakciók számára az adatbázis-zár megszerzését. Mindegyik megmarad mindaddig, amíg a tranzakció el nem készül vagy visszafordul.

Érdemes észrevenni, hogy egyszerre csak egy zárat szerezhetünk be. Ha lehetetlen a PerzisztenciaKivétel dobják.

2.1. PESSIMISTIC_READ

Amikor csak adatokat akarunk olvasni, és nem találkozunk piszkos olvasásokkal, használhatjuk PESSIMISTIC_READ (megosztott zár). Ennek ellenére nem tudunk frissíteni vagy törölni.

Néha előfordul, hogy az általunk használt adatbázis nem támogatja a PESSIMISTIC_READ zár, így lehetséges, hogy megszerezzük a PESSIMISTIC_WRITE zár helyett.

2.2. PESSIMISTIC_WRITE

Minden olyan tranzakciónak, amelynek zárolását kell megszereznie az adatokon, és azokat módosítania kell, meg kell szereznie a PESSIMISTIC_WRITE zár. Szerint a JPA specifikáció, tartás PESSIMISTIC_WRITE A zárolás megakadályozza, hogy más tranzakciók olvassák, frissítsék vagy töröljék az adatokat.

Felhívjuk figyelmét, hogy egyes adatbázis-rendszerek több verziós egyidejűség-vezérlést valósítanak meg, amely lehetővé teszi az olvasók számára a már letiltott adatok lekérését.

2.3. PESSIMISTIC_FORCE_INCREMENT

Ez a zár hasonlóan működik PESSIMISTIC_WRITE, de azért vezették be, hogy együttműködjön verziószámú entitásokkal - olyan entitásokkal, amelyekhez egy attribútumot feljegyeztek @Változat.

A verziószámú entitások bármilyen frissítését megelőzheti a PESSIMISTIC_FORCE_INCREMENT zár. A zár megszerzése a verzió oszlopának frissítését eredményezi.

A kitartás-szolgáltató feladata annak meghatározása, hogy támogatja-e PESSIMISTIC_FORCE_INCREMENT változatlan entitások számára vagy sem. Ha nem, akkor dobja a PersistanceException.

2.4. Kivételek

Jó tudni, melyik kivétel fordulhat elő pesszimista reteszelés közben. JPA a specifikáció különböző típusú kivételeket tartalmaz:

  • PessimisticLockException - azt jelzi, hogy a zár megszerzése vagy a megosztott zárattá konvertálása nem sikerül, és tranzakció szintű visszagörgetést eredményez
  • LockTimeoutException - azt jelzi, hogy egy zár megszerzése vagy a megosztott zár átalakítása exkluzív időkorlátra, és utasításszintű visszagörgetést eredményez
  • PersistanceException - azt jelzi, hogy perzisztencia probléma merült fel. PersistanceException és altípusai, kivéve NoResultException, NonUniqueResultException,LockTimeoutException, és QueryTimeoutException, a visszagörgetendő aktív tranzakciót jelöli.

3. Pesszimista zárak használata

Néhány lehetőség van egy pesszimista zár konfigurálására egyetlen rekordon vagy rekordcsoporton. Lássuk, hogyan kell csinálni a JPA-ban.

3.1. megtalálja

Valószínűleg ez a legegyszerűbb mód. Elég átadni a LockModeType objektum az. paramétereként megtalálja módszer:

entitásManager.find (Student.class, studentId, LockModeType.PESSIMISTIC_READ);

3.2. Lekérdezés

Ezenkívül használhatjuk a Lekérdezés objektumot is, és hívja a setLockMode beállító paraméterként zárolási üzemmóddal:

Lekérdezés = entitásManager.createQuery ("a hallgatótól ahol studentId =: studentId"); query.setParameter ("studentId", studentId); query.setLockMode (LockModeType.PESSIMISTIC_WRITE); query.getResultList ()

3.3. Kifejezett zárolás

A keresési módszerrel lekért eredmények manuálisan is zárolhatók:

Student resultStudent = entitásManager.find (Student.class, studentId); entitásManager.lock (resultStudent, LockModeType.PESSIMISTIC_WRITE);

3.4. Frissítés

Ha felül akarjuk írni az entitás állapotát a Frissítés módszerrel zárat is beállíthatunk:

Student resultStudent = entitásManager.find (Student.class, studentId); entitásManager.refresh (resultStudent, LockModeType.PESSIMISTIC_FORCE_INCREMENT);

3.5. NamedQuery

@NévQuery az annotáció lehetővé teszi számunkra a zárolási mód beállítását is:

@NamedQuery (név = "lockStudent", lekérdezés = "SELECT s FROM Student s WHERE s.id LIKE: studentId", lockMode = PESSIMISTIC_READ)

4. Zárja be a hatókört

A zárolási hatókör paraméter meghatározza, hogyan kell kezelni a lezárt entitás zárolási kapcsolatait. Lehetőség van egy zárolás megszerzésére csak egy lekérdezésben definiált entitásra, vagy kiegészítően blokkolhatja annak kapcsolatait.

A használható kör konfigurálásához PessimisticLockScope enum. Két értéket tartalmaz: NORMÁL és KITERJEDT.

A hatókört úgy állíthatjuk be, hogy átadunk egy paramétertjavax.persistance.lock.scope' val vel PessimisticLockScope érték a megfelelő módszer argumentumaként EntityManager, Lekérdezés, TypedQuery vagy NamedQuery:

Térkép tulajdonságai = új HashMap (); map.put ("javax.persistence.lock.scope", PessimisticLockScope.EXTENDED); entitásManager.find (Student.class, 1L, LockModeType.PESSIMISTIC_WRITE, tulajdonságok); 

4.1. PesszimistaLockScope.NORMAL

Tudnunk kell, hogy a PesszimistaLockScope.NORMAL az alapértelmezett hatókör. Ezzel a zárolási lehetőséggel lezárjuk magát az entitást. Egyesített örökséggel együtt használva az ősöket is lezárja.

Nézzük meg a mintakódot két entitással:

@Entity @Inheritance (stratégia = InheritanceType.JOINED) nyilvános osztály Személy {@Id private Long id; privát karakterlánc neve; privát karakterlánc vezetéknév; // getters and setters} @Entity public class Alkalmazott meghosszabbítja Person {private BigDecimal fizetést; // szerelők és beállítók}

Amikor zárat akarunk szerezni a Munkavállaló, megfigyelhetjük a SQL a két entitáson átívelő lekérdezés:

Válassza ki a t0.ID, t0.DTYPE, t0.LASTNAME, t0.NAME, t1.ID, t1.KÖZÖSSÉGET T0 SZEMÉLYBŐL, MUNKAVÁLLALÓT t1 WHERE ÉS (t0.DTYPE =?))) FRISSÍTÉSRE

4.2. PessimisticLockScope.MEGTÖLTÖTT

A KITERJEDT hatálya ugyanazt a funkciót fedi le, mint a NORMÁL. Továbbá, képes blokkolni a kapcsolódó entitásokat egy csatlakozási táblában.

Egyszerűen fogalmazva, a jelöléssel ellátott entitásokkal működik @ElementCollection vagy @1-1, @Egy a sokhoz stb @JoinTable.

Nézzük meg a mintakódot a @ElementCollection kommentár:

@Entity public class Ügyfél {@Id private Long customerId; privát karakterlánc neve; privát karakterlánc vezetéknév; @ElementCollection @CollectionTable (név = "ügyfél_cím") privát lista címlista; // getters and setters} @ Beágyazható nyilvános osztály Cím {private String country; privát String város; // szerelők és beállítók}

Elemezzünk néhány kérdést a Vevő entitás:

KIVÁLASZTÁS CUSTOMERID, LASTNAME, NÉV AZ ÜGYFÉLBŐL HOL

Láthatjuk, hogy kétFRISSÍTÉSRE’Olyan lekérdezések, amelyek egy sort zárnak az ügyféltáblában, valamint egy sort a csatlakozási táblázatban.

Egy másik érdekes tény, amellyel tisztában kell lennünk, az, hogy nem minden kitartást biztosító szolgáltató támogatja a zárolási hatóköröket.

5. A Lock Timeout beállítása

A zár hatókörének beállítása mellett beállíthatunk egy másik zárparamétert is - az időtúllépést. Az időkorlát értéke az ezredmásodpercek száma, amelyet várni kell a zár megszerzéséig a LockTimeoutException bekövetkezik.

Az időkorlát értékét a zárolási hatókörökhöz hasonlóan megváltoztathatjuk ajavax.persistence.lock.timeout ' a megfelelő számú milliszekundummal.

Megadható a „nincs várakozás” zárolás is, ha az időkorlát értékét nullára változtatja. Nem szabad megfeledkeznünk arról, hogy vannak adatbázis-illesztőprogramok, amelyek ne támogassa az időkorlát értékének ilyen módon történő beállítását.

Térkép tulajdonságai = új HashMap (); map.put ("javax.persistence.lock.timeout", 1000L); entitásManager.find (Student.class, 1L, LockModeType.PESSIMISTIC_READ, tulajdonságok);

6. Következtetés

Ha a megfelelő elszigetelési szint beállítása nem elegendő az egyidejű tranzakciók kezeléséhez, a JPA pesszimista zárolást biztosít számunkra. Lehetővé teszi számunkra a különböző tranzakciók elkülönítését és összehangolását, hogy ne érhessék el ugyanahhoz az erőforráshoz egyszerre.

Ennek elérése érdekében választhatunk a megvitatott zárak típusai között, és ennek következtében módosíthatjuk az olyan paramétereket, mint azok hatóköre vagy időtúllépése.

Másrészt emlékeznünk kell arra, hogy az adatbázis zárak megértése ugyanolyan fontos, mint az alapul szolgáló adatbázis rendszerek mechanizmusainak megértése. Fontos szem előtt tartani azt is, hogy a pesszimista zárak viselkedése a kitartás szolgáltatótól függ, akivel dolgozunk.

Végül az oktatóanyag forráskódja elérhető a GitHubon hibernált állapotra és az EclipseLink számára.


$config[zx-auto] not found$config[zx-overlay] not found