TransactionRequiredException Error
1. Oversigt
I denne vejledning skal vi undersøge årsagen til TransactionRequiredException fejl og hvordan man løser det.
2. TransactionRequiredException
Denne fejl opstår typisk, når vi prøver at udføre en databasehandling, der ændrer databasen uden en transaktion.
For eksempel forsøg på at opdatere en post uden en transaktion:
Forespørgsel updateQuery = session.createQuery ("UPDATE Post p SET p.title =? 1, p.body =? 2 WHERE p.id =? 3"); updateQuery.setParameter (1, titel); updateQuery.setParameter (2, body); updateQuery.setParameter (3, id); updateQuery.executeUpdate ();
Hæver en undtagelse med en besked på følgende linjer:
... javax.persistence.TransactionRequiredException: Udførelse af en opdaterings- / sletningsforespørgsel på org.hibernate.query.internal.AbstractProducedQuery.executeUpdate (AbstractProducedQuery.java:1586) ...
3. Levering af en transaktion
Den åbenlyse løsning er at indpakke enhver databasemodificerende operation i en transaktion:
Transaktion txn = session.beginTransaction (); Forespørgsel updateQuery = session.createQuery ("UPDATE Post p SET p.title =? 1, p.body =? 2 WHERE p.id =? 3"); updateQuery.setParameter (1, titel); updateQuery.setParameter (2, body); updateQuery.setParameter (3, id); updateQuery.executeUpdate (); txn.commit ();
I kodestykket ovenfor initierer og begår vi manuelt transaktionen. Selvom i et Spring Boot-miljø kan vi opnå dette ved hjælp af @Transaktionel kommentar.
4. Transaktionsstøtte om foråret
Hvis vi ønsker mere finkornet kontrol, kan vi bruge Spring's Transaktionsskabelon. Fordi dette gør det muligt for programmøren at udløse vedholdenheden af et objekt umiddelbart før du fortsætter med kodeudførelsen af en metode.
Lad os for eksempel sige, at vi vil opdatere indlægget, inden vi sender en e-mail-underretning:
offentlig ugyldig opdatering () {entityManager.createQuery ("UPDATE Post p SET p.title =? 2, p.body =? 3 WHERE p.id =? 1") // parametre .executeUpdate (); Send e-mail(); }
Anvendelse af @Transaktionel til ovenstående metode kan medføre, at e-mailen sendes på trods af en undtagelse i opdateringsprocessen. Dette skyldes, at transaktionen kun begås, når metoden afsluttes og er ved at vende tilbage til den, der ringer op.
Derfor opdateres indlægget inden for en Transaktionsskabelon forhindrer dette scenario, da det vil begå operationen med det samme:
offentlig ugyldig opdatering () {transactionTemplate.execute (transactionStatus -> {entityManager.createQuery ("UPDATE Post p SET p.title =? 2, p.body =? 3 WHERE p.id =? 1") // parametre. executeUpdate (); transactionStatus.flush (); return null;}); Send e-mail(); }
5. Konklusion
Afslutningsvis er det generelt en god praksis at indpakke databaseoperationer i en transaktion. Det hjælper med at forhindre korruption af data. Den komplette kildekode er tilgængelig på Github.