Chyba TransactionRequiredException

1. Prehľad

V tomto výučbe budeme skúmať príčinu TransactionRequiredException chyba a ako to riesit.

2. TransactionRequiredException

Táto chyba sa zvyčajne vyskytuje, keď sa pokúšame vykonať databázovú operáciu, ktorá upraví databázu bez transakcie.

Napríklad pokus o aktualizáciu záznamu bez transakcie:

Dotaz updateQuery = session.createQuery ("UPDATE Post p SET p.title =? 1, p.body =? 2 KDE p.id =? 3"); updateQuery.setParameter (1, nadpis); updateQuery.setParameter (2, telo); updateQuery.setParameter (3, id); updateQuery.executeUpdate ();

Zvýši výnimku správou v nasledujúcich riadkoch:

... javax.persistence.TransactionRequiredException: vykonanie dotazu na aktualizáciu / odstránenie na org.hibernate.query.internal.AbstractProducedQuery.executeUpdate (AbstractProducedQuery.java:1586) ...

3. Poskytnutie transakcie

Zrejmým riešením je zabaliť každú operáciu upravujúcu databázu do transakcie:

Transakcia txn = session.beginTransaction (); Dotaz updateQuery = session.createQuery ("UPDATE Post p SET p.title =? 1, p.body =? 2 KDE p.id =? 3"); updateQuery.setParameter (1, nadpis); updateQuery.setParameter (2, telo); updateQuery.setParameter (3, id); updateQuery.executeUpdate (); txn.commit ();

V útržku kódu vyššie uskutočňujeme transakciu ručne a zaväzujeme ju. Hoci v prostredí Spring Boot to môžeme dosiahnuť použitím @ Transakčné anotácia.

4. Podpora transakcií na jar

Ak chceme jemnejšiu kontrolu, môžeme použiť Spring TransactionTemplate. Pretože to umožňuje programátorovi spustiť perzistenciu objektu bezprostredne pred vykonaním kódu metódy.

Povedzme napríklad, že chceme príspevok aktualizovať pred odoslaním e-mailovej notifikácie:

public void update () {entityManager.createQuery ("UPDATE Post p SET p.title =? 2, p.body =? 3 WHERE p.id =? 1") // parametre .executeUpdate (); poslať email(); }

Uplatňovanie @ Transakčné vyššie uvedeným spôsobom môže spôsobiť, že bude e-mail odoslaný napriek výnimke v procese aktualizácie. Je to tak preto, lebo transakcia bude vykonaná až po ukončení metódy a návrate volajúceho.

Preto aktualizácia príspevku v rámci a TransactionTemplate zabráni tomuto scenáru, pretože operáciu vykoná okamžite:

public void update () {transactionTemplate.execute (transactionStatus -> {entityManager.createQuery ("UPDATE Post p SET p.title =? 2, p.body =? 3 KDE p.id =? 1") // parametre .executeUpdate (); transactionStatus.flush (); return null;}); poslať email(); }

5. Záver

Záverom je, že vo všeobecnosti je dobrým zvykom zabaliť operácie databázy do transakcie. Pomáha predchádzať poškodeniu údajov. Celý zdrojový kód je k dispozícii na stránkach Github.


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