Kontext JPA / dlhodobého spánku

1. Prehľad

Poskytovatelia perzistencie, ako je režim dlhodobého spánku, využívajú kontext perzistencie na správu životného cyklu entity v aplikácii.

V tomto tutoriále začneme zavedením kontextu vytrvalosti, potom uvidíme, prečo je to dôležité. Na záver uvidíme na príkladoch rozdiel medzi kontextom perzistencie s rozsahom transakcií a kontextom perzistencie s rozšíreným rozsahom.

2. Kontext vytrvalosti

Pozrime sa na oficiálnu definíciu kontextu perzistencie:

Inštancia EntityManager je spojená s kontextom vytrvalosti. Kontext perzistencie je sada inštancií entít, v ktorých pre každú pretrvávajúcu identitu entity existuje jedinečná inštancia entity. V kontexte perzistencie sa spravujú inštancie entít a ich životný cyklus. Rozhranie EntityManager API sa používa na vytváranie a odstraňovanie pretrvávajúcich inštancií entít, na vyhľadávanie entít podľa ich primárneho kľúča a na dopytovanie entít.

Vyššie uvedené vyhlásenie sa teraz môže javiť ako trochu zložité, ale keď budeme pokračovať, bude to mať úplný zmysel. Kontextom perzistencie je vyrovnávacia pamäť prvej úrovne, kde sú všetky entity načítané z databázy alebo uložené do databázy. Nachádza sa medzi našou aplikáciou a trvalým úložiskom.

Kontext vytrvalosti sleduje všetky zmeny vykonané v spravovanej entite. Ak sa počas transakcie niečo zmení, potom je entita označená ako špinavá. Po dokončení transakcie sa tieto zmeny vyprázdnia do trvalého úložiska.

The EntityManager je rozhranie, ktoré nám umožňuje interagovať s perzistenciou. Kedykoľvek použijeme EntityManager, v skutočnosti interagujeme s kontextom vytrvalosti.

Ak každá zmena vykonaná v entite zavolá na trvalé úložisko, môžeme si predstaviť, koľko hovorov sa uskutoční. To povedie k dopadu na výkon, pretože trvalé volania úložiska sú drahé.

3. Typ kontextu perzistencie

Kontexty perzistencie sú k dispozícii v dvoch typoch:

  • Kontext vytrvalosti s rozsahom transakcie
  • Kontext vytrvalosti s rozšíreným rozsahom

Poďme sa na každú z nich pozrieť.

3.1 Kontext perzistencie s rozsahom transakcie

Kontext trvalosti transakcie je viazaný na transakciu. Hneď ako sa transakcia dokončí, entity prítomné v kontexte perzistencie sa vyprázdnia do trvalého úložiska.

Keď vykonáme akúkoľvek operáciu v rámci transakcie, EntityManager kontroluje kontext vytrvalosti. Ak nejaký existuje, použije sa. V opačnom prípade vytvorí kontext vytrvalosti.

Predvolený typ kontextu vytrvalosti jePersistenceContextType.TRANSACTION. Povedať EntityManager na použitie kontextu perzistencie transakcie ho jednoducho anotujeme @PersistenceContext:

@PersistenceContext private EntityManager entityManager;

3.2 Kontext trvalosti s rozšíreným rozsahom

Kontext rozšíreného pretrvávania sa môže vzťahovať na viaceré transakcie. Môžeme pretrvať entitu bez transakcie, ale nemôžeme ju vyprázdniť bez transakcie.

Povedať EntityManager na použitie kontextu trvalosti s rozšíreným rozsahom je potrebné použiť typu atribút @PersistenceContext:

@PersistenceContext (type = PersistenceContextType.EXTENDED) private EntityManager entityManager;

V fazuli bez štátnej príslušnosti fazuľa kontext rozšírenej perzistencie v jednej zložke úplne nevie o žiadnom kontexte perzistencie inej zložky. To platí, aj keď sú obe v rovnakej transakcii.

Povedzme, že pretrvávame v entite v metóde Komponent A, ktorá prebieha v transakcii. Potom zavoláme nejakú metódu komponentu B. V komponente B kontext vytrvalosti metódy nenájdeme entitu, ktorú sme v metóde Komponent pretrvávali predtým A.

4. Príklad kontextu perzistencie

Teraz, keď vieme dosť o kontexte vytrvalosti, je čas sa ponoriť do príkladu. Urobíme rôzne prípady použitia s kontextom perzistencie transakcií a kontextom rozšírenej perzistencie.

Najprv si vytvorme našu triedu služieb, TransctionPersistenceContextUserService:

@Component public class TransctionPersistenceContextUserService {@PersistenceContext private EntityManager entityManager; @Transactional public User insertWithTransaction (užívateľský užívateľ) {entityManager.persist (užívateľ); návratový užívateľ; } public User insertWithoutTransaction (User user) {entityManager.persist (user); návratový užívateľ; } verejné hľadanie používateľa (dlhé ID) {návrat entityManager.find (User.class, id); }}

Ďalšia trieda, ExtendedPersistenceContextUserService, je veľmi podobný vyššie uvedenému, s výnimkou @PersistenceContext anotácia. Tentokrát prechádzame PersistenceContextType.EXTENDED do typu jeho parameter @PersistenceContext anotácia:

@ Komponenta verejná trieda ExtendedPersistenceContextUserService {@PersistenceContext (type = PersistenceContextType.EXTENDED) súkromný EntityManager entityManager; // Zvyšný kód rovnaký ako vyššie}

5. Testovacie prípady

Teraz, keď máme nastavené naše triedy služieb, je čas urobiť rôzne prípady použitia s kontextom perzistencie transakcií a kontextom rozšírenej perzistencie.

5.1 Testovanie kontextu perzistencie transakcie

Vytrvajme a Používateľ entita používajúca kontext perzistencie vymedzený transakciami. Entita bude uložená v trvalom úložisku. Potom overíme uskutočnením hovoru pomocou nášho rozšíreného kontextu perzistencie EntityManager:

Používateľ user = nový používateľ (121L, "Devender", "admin"); transctionPersistenceContext.insertWithTransaction (užívateľ); Používateľ userFromTransctionPersistenceContext = transctionPersistenceContext .find (user.getId ()); assertNotNull (userFromTransctionPersistenceContext); Používateľ userFromExtendedPersistenceContext = extendedPersistenceContext .find (user.getId ()); assertNotNull (userFromExtendedPersistenceContext);

Keď sa pokúsime vložiť a Používateľ subjekt bez transakcie TransactionRequiredException bude vyhodené:

@Test (očakáva sa = TransactionRequiredException.class) public void testThatUserSaveWithoutTransactionThrowException () {User user = new User (122L, "Devender", "admin"); transctionPersistenceContext.insertWithoutTransaction (užívateľ); }

5.2 Testovanie kontextu rozšírenej perzistencie

Ďalej vydržme používateľa s kontextom rozšírenej perzistencie a bez transakcie. The Používateľ entita bude uložená v kontexte trvalosti (cache), ale nie v trvalom úložisku:

Používateľ user = nový používateľ (123L, "Devender", "admin"); extendedPersistenceContext.insertWithoutTransaction (užívateľ); Používateľ userFromExtendedPersistenceContext = extendedPersistenceContext .find (user.getId ()); assertNotNull (userFromExtendedPersistenceContext); Používateľ userFromTransctionPersistenceContext = transctionPersistenceContext .find (user.getId ()); assertNull (userFromTransctionPersistenceContext);

V kontexte pretrvávania akejkoľvek trvalej identity entity bude existovať jedinečná inštancia entity. Ak sa pokúsime zachovať inú entitu s rovnakým identifikátorom:

@Test (očakáva sa = EntityExistsException.class) public void testThatPersistUserWithSameIdentifierThrowException () {User user1 = new User (126L, "Devender", "admin"); Používateľ user2 = nový používateľ (126L, "Devender", "admin"); extendedPersistenceContext.insertWithoutTransaction (user1); extendedPersistenceContext.insertWithoutTransaction (user2); }

Uvidíme EntityExistsException:

javax.persistence.EntityExistsException: K relácii už bol priradený iný objekt s rovnakou hodnotou identifikátora.

Kontext rozšírenej perzistencie v rámci transakcie uloží entitu v trvalom úložisku na konci transakcie:

Používateľ user = nový používateľ (127L, "Devender", "admin"); extendedPersistenceContext.insertWithTransaction (užívateľ); Používateľ userFromDB = transctionPersistenceContext.find (user.getId ()); assertNotNull (userFromDB);

Kontext rozšírenej perzistencie pri použití v rámci transakcie vyprázdni entity v medzipamäti na trvalé úložisko. Najprv entitu ponecháme bez transakcie. Ďalej v transakcii pretrvávame s ďalšou entitou:

Používateľ user1 = nový používateľ (124L, „Devender“, „admin“); extendedPersistenceContext.insertWithoutTransaction (user1); Používateľ user2 = nový používateľ (125L, "Devender", "admin"); extendedPersistenceContext.insertWithTransaction (user2); Používateľ user1FromTransctionPersistenceContext = transctionPersistenceContext .find (user1.getId ()); assertNotNull (user1FromTransctionPersistenceContext); Používateľ user2FromTransctionPersistenceContext = transctionPersistenceContext .find (user2.getId ()); assertNotNull (user2FromTransctionPersistenceContext);

6. Záver

V tomto tutoriáli sme získali dobré porozumenie kontextu vytrvalosti.

Najprv sme sa pozreli na kontext perzistencie transakcie, ktorý existuje počas celej doby platnosti transakcie. Potom sme sa pozreli na kontext rozšírenej perzistencie, ktorý môže zahŕňať rôzne transakcie.

Vzorový kód je ako vždy k dispozícii na stránkach GitHub.


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