TransactionRequiredException-fout

1. Overzicht

In deze tutorial gaan we de oorzaak van de TransactionRequiredException fout en hoe deze op te lossen.

2. TransactionRequiredException

Deze fout treedt meestal op wanneer we een databasebewerking proberen uit te voeren die de database wijzigt zonder een transactie.

Als u bijvoorbeeld probeert een record bij te werken zonder een transactie:

Query updateQuery = session.createQuery ("UPDATE Post p SET p.title =? 1, p.body =? 2 WAAR p.id =? 3"); updateQuery.setParameter (1, titel); updateQuery.setParameter (2, body); updateQuery.setParameter (3, id); updateQuery.executeUpdate ();

Zal een uitzondering genereren met een bericht in de volgende zin:

... javax.persistence.TransactionRequiredException: Een update / delete-query uitvoeren op org.hibernate.query.internal.AbstractProducedQuery.executeUpdate (AbstractProducedQuery.java:1586) ...

3. Een transactie verstrekken

De voor de hand liggende oplossing is om elke database-wijzigende bewerking in een transactie te verpakken:

Transactie txn = session.beginTransaction (); Query updateQuery = session.createQuery ("UPDATE Post p SET p.title =? 1, p.body =? 2 WAAR p.id =? 3"); updateQuery.setParameter (1, titel); updateQuery.setParameter (2, body); updateQuery.setParameter (3, id); updateQuery.executeUpdate (); txn.commit ();

In het bovenstaande codefragment initiëren en plegen we de transactie handmatig. Hoewel in een Spring Boot-omgeving kunnen we dit bereiken door de @Transactional annotatie.

4. Transactieondersteuning in het voorjaar

Als we meer fijnmazige controle willen, kunnen we Spring gebruiken Transactietemplate. Omdat hierdoor de programmeur de persistentie van een object kan activeren onmiddellijk voordat hij verdergaat met de code-uitvoering van een methode.

Laten we bijvoorbeeld zeggen dat we het bericht willen bijwerken voordat we een e-mailmelding sturen:

public void update () {entityManager.createQuery ("UPDATE Post p SET p.title =? 2, p.body =? 3 WAAR p.id =? 1") // parameters .executeUpdate (); sendEmail (); }

Het toepassen van de @Transactional de bovenstaande methode kan ertoe leiden dat de e-mail wordt verzonden ondanks een uitzondering in het updateproces. Dit komt omdat de transactie alleen wordt vastgelegd wanneer de methode wordt afgesloten en op het punt staat terug te keren naar de beller.

Daarom het bijwerken van het bericht binnen een Transactietemplate zal dit scenario voorkomen omdat het de bewerking onmiddellijk zal vastleggen:

public void update () {transactionTemplate.execute (transactionStatus -> {entityManager.createQuery ("UPDATE Post p SET p.title =? 2, p.body =? 3 WAAR p.id =? 1") // parameters .executeUpdate (); transactionStatus.flush (); retourneer null;}); sendEmail (); }

5. Conclusie

Kortom, het is over het algemeen een goede gewoonte om databasebewerkingen in een transactie te verpakken. Het helpt bij het voorkomen van gegevensbeschadiging. De volledige broncode is beschikbaar op Github.


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