Optimista zárolás a JPA-ban

1. Bemutatkozás

A vállalati alkalmazások esetében elengedhetetlen az adatbázis egyidejű hozzáférésének megfelelő kezelése. Ez azt jelenti, hogy képesek vagyunk több tranzakció hatékony és legfontosabb, hibabiztos kezelésére.

Sőt, biztosítanunk kell, hogy az adatok konzisztensek maradjanak az egyidejű olvasások és frissítések között.

Ennek elérése érdekében használhatjuk a Java Persistence API által biztosított optimista zárolási mechanizmust. Ebből az következik, hogy ugyanazon adatokon egyszerre több frissítés sem zavarja egymást.

2. Az optimista zárolás megértése

Az optimista reteszelés érdekében rendelkeznünk kell egy entitással, amely egy tulajdonságot tartalmaz a @Változat annotáció. Használata közben minden adatot olvasó tranzakció megtartja a version tulajdonság értékét.

Mielőtt a tranzakció frissíteni akarna, újra ellenőrzi a version tulajdonságot.

Ha az érték időközben megváltozott an OptimisticLockException dobják. Ellenkező esetben a tranzakció végrehajtja a frissítést, és növeli az érték verzió tulajdonságát.

3. Pesszimista zárolás és optimista zárolás

Jó tudni, hogy az optimista zárral ellentétben a JPA pesszimista zárat ad nekünk. Ez egy másik mechanizmus az adatok egyidejű hozzáférésének kezelésére.

A pesszimista zárolást az egyik korábbi cikkünkben tárgyaljuk - Pesszimista zárolás a JPA-ban. Derítsük ki, mi a különbség, és hogyan profitálhatunk az egyes reteszelési típusokból.

Ahogy korábban mondtuk, Az optimista zárolás az entitások változásainak észlelésén alapul, verziójuk attribútumának ellenőrzésével. Ha bármilyen egyidejű frissítés történik, OptmisticLockException bekövetkezik. Ezt követően újra megpróbálhatjuk frissíteni az adatokat.

El tudjuk képzelni, hogy ez a mechanizmus alkalmas olyan alkalmazásokra, amelyek sokkal többet olvasnak, mint frissítenek vagy törölnek. Sőt, hasznos olyan helyzetekben, amikor az entitásokat egy ideig le kell választani, és a zárakat nem lehet tartani.

Éppen ellenkezőleg, a pesszimista zárolási mechanizmus magában foglalja az entitások adatbázis-szintű zárolását.

Minden tranzakció lezárhatja az adatokat. Amíg a zárat tartja, egyetlen tranzakció sem olvashatja, sem törölheti, sem nem frissítheti a lezárt adatokat. Feltételezhetjük, hogy a pesszimista zárolás holtpontokat eredményezhet. Ez azonban az adatok nagyobb integritását biztosítja, mint az optimista zárolás.

4. Verzióattribútumok

A verzióattribútumok tulajdonságai a @Változat annotáció. Az optimista reteszeléshez szükségesek. Nézzük meg az entitásosztály mintáját:

@Entity public class Student {@Id private Long id; privát karakterlánc neve; privát karakterlánc vezetéknév; @Version privát egész szám; // szerelők és beállítók}

A verzióattribútumok deklarálásakor számos szabályt be kell tartanunk:

  • minden entitásosztálynak csak egy verzióattribútuma lehet
  • több táblához leképezett entitás számára az elsődleges táblába kell helyezni
  • A version attribútum típusának a következők egyikének kell lennie: int, Egész szám, hosszú, Hosszú, rövid, Rövid, java.sql.Timestamp

Tudnunk kell, hogy entitáson keresztül lekérhetjük a verzióattribútum értékét, de nem szabad frissíteni vagy növelni. Ezt csak a kitartás-szolgáltató teheti meg, így az adatok konzisztensek maradnak.

Érdemes észrevenni, hogy a kitartás-szolgáltatók támogatni tudják az optimista zárolást azoknál az entitásoknál, amelyek nem rendelkeznek verzióattribútumokkal. Mégis, érdemes optimista zárolással mindig a verzióattribútumokat beilleszteni.

Ha megpróbálunk lezárni egy entitást, amely nem tartalmaz ilyen attribútumot, és a perzisztencia-szolgáltató nem támogatja azt, akkor egy PersitenceException.

5. Lezárási módok

A JPA két különböző optimista zárolási módot (és két álnevet) biztosít számunkra:

  • OPTIMISTA - optimista olvasási zárat kap minden változat-attribútumot tartalmazó entitás számára
  • OPTIMISTIC_FORCE_INCREMENT - ugyanolyan optimista zárat kap, mint OPTIMISTA és emeli a verzió attribútum értékét
  • OLVAS - ez a szinonimája OPTIMISTA
  • ÍR - ez a szinonimája OPTIMISTIC_FORCE_INCREMENT

A fent felsorolt ​​összes típust megtalálhatjuk a LockModeType osztály.

5.1. OPTIMISTA (OLVAS)

Mint már tudjuk, OPTIMISTA és OLVAS a zárolási módok szinonimák. A JPA specifikáció azonban javasolja, hogy használjuk OPTIMISTA új alkalmazásokban.

Valahányszor kérjük a OPTIMISTA zárolási mód, a perzisztencia-szolgáltató megakadályozza adataink piszkos és nem megismételhető olvasásait.

Egyszerűen fogalmazva, biztosítania kell, hogy bármely tranzakció nem változtat meg egy másik tranzakció adatait:

  • frissítette vagy törölte, de nem követte el
  • időközben sikeresen frissült vagy törölve

5.2. OPTIMISTIC_INCREMENT (ÍR)

Ugyanaz, mint korábban, OPTIMISTIC_INCREMENT és ÍR szinonimák, de az előbbi előnyösebb.

OPTIMISTIC_INCREMENT ugyanazoknak a feltételeknek kell megfelelniük, mint OPTIMISTA zár mód. Ezenkívül növeli a verzióattribútum értékét. Azonban nincs meghatározva, hogy azonnal meg kell-e tenni, vagy el lehet-e halasztani, amíg el nem végzik vagy el nem öblítik.

Érdemes tudni, hogy a perzisztenciát biztosító szolgáltató megengedett OPTIMISTIC_INCREMENT funkcionalitás mikor OPTIMISTA zárolási módot igényel.

6. Az optimista zár használata

Nem szabad megfeledkeznünk arról, hogy a verziószámú entitásoknál alapértelmezés szerint optimista zárolás érhető el. Mégis többféle módon lehet kifejezetten kérni.

6.1. megtalálja

Az optimista zár kérésére átadhatjuk a megfelelőt LockModeType mint argumentum a módszer megtalálásához EntityManager:

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

6.2. Lekérdezés

A zárolás engedélyezésének másik módja a setLockMode a metódusa Lekérdezés tárgy:

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

6.3. Kifejezett zárolás

Az EnitityManager hívásával zárat állíthatunk be zár módszer:

Diák diák = entityManager.find (Student.class, id); entitásManager.lock (tanuló, LockModeType.OPTIMISTIC);

6.4. Frissítés

Felhívhatjuk a Frissítés módszer ugyanúgy, mint az előző módszer:

Diák diák = entityManager.find (Student.class, id); entitásManager.refresh (tanuló, LockModeType.READ);

6.5. NamedQuery

Az utolsó lehetőség a @NamedQuery használata a lockMode ingatlan:

@NamedQuery (name = "optimisticLock", query = "SELECT s FROM Student s WHERE s.id LIKE: id", lockMode = WRITE)

7. OptimisticLockException

Amikor a kitartásszolgáltató optimista zárolási konfliktusokat fedez fel az entitásokon, akkor dob OptimisticLockException. Tudnunk kell, hogy a kivétel miatt az aktív tranzakció mindig megjelölésre kerül.

Jó tudni, hogyan reagálhatunk OptimisticLockException. Kényelmesen ez a kivétel hivatkozást tartalmaz az ütköző entitásra. A kitartást biztosító szolgáltatónak azonban nem kötelező minden helyzetben ellátnia. Nincs garancia arra, hogy az objektum elérhető lesz.

Van azonban egy ajánlott módszer a leírt kivétel kezelésére. Újra be kell töltenünk az entitást újratöltéssel vagy frissítéssel. Lehetőleg egy új tranzakcióban. Ezt követően még egyszer megpróbálhatjuk frissíteni.

8. Következtetés

Ebben az oktatóanyagban megismerkedtünk egy olyan eszközzel, amely segíthet a párhuzamos tranzakciók lebonyolításában. Az optimista zárolás az entitásokban szereplő verzióattribútumokat használja az egyidejű módosítások vezérlésére.

Ezért biztosítja, hogy a frissítéseket vagy törléseket ne írják felül vagy veszítsék el csendesen. A pesszimista zárolással szemben nem zárja le az entitásokat az adatbázis szintjén, következésképpen nem kiszolgáltatott a DB holtpontjainak.

Megtudtuk, hogy az optimista zárolás alapértelmezés szerint engedélyezve van a verziószámú entitásoknál. Számos módja van azonban külön kérésére különféle zárolási módok használatával.

Egy másik tény, amire emlékeznünk kell, hogy valahányszor ellentmondó frissítések érkeznek az entitásokról, számolnunk kell egy OptimisticLockException.

Végül az oktatóanyag forráskódja elérhető a GitHubon.