4.1 Introduksjon til transaksjoner i Hibernate
Til alt det ovennevnte vil jeg gjerne legge til informasjon om transaksjoner. Som du allerede vet, er en transaksjon en gruppe handlinger som bare må utføres samlet . Hvis en handling mislyktes eller ble utført med en feil, må alle andre handlinger kanselleres.
![](https://cdn.codegym.cc/images/article/f5ab4cb5-18c2-42e5-83a4-9a4d93f30414/1024.jpeg)
Hibernate kan jobbe med to typer transaksjoner:
- JDBC
- JTA
En JDBC-transaksjon er faktisk en databasetransaksjon. Det er knyttet til å jobbe med databasen, til JDBC-tilkoblingen. Og han sørger for at handlingene når man jobber med databasen blir utført som de skal: enten alt eller ingenting.
JTA - Transaksjon er en transaksjon på applikasjonsnivå. Den er ikke knyttet til noen database. Dens oppgave er å sikre at visse handlinger utføres: enten alt eller ingenting.
For eksempel kan du skrive data til flere forskjellige databaser innenfor en enkelt JTA-transaksjon. Så hvis det oppstår en feil, må JTA-transaksjonen rulle tilbake endringene i alle databaser. Selv de som ble utført med suksess i form av en bestemt database.
4.2 Transaksjonsgrensesnitt i dvalemodus
I Hibernate-biblioteket er en transaksjon representert av Transaction-grensesnittet, som kan ha forskjellige implementeringer. For eksempel, når du arbeider med Spring, tilbyr Spring sin egen JTA-transaksjonsmekanisme.
Metodene for dette grensesnittet er:
# | Metode | Beskrivelse |
---|---|---|
1 | begynne() | Starter en ny transaksjon |
2 | begå() | Avslutter transaksjonen, pusher/forplikter alle endringer |
3 | rollback() | Ruller tilbake gjeldende transaksjon |
4 | setTimeout (int sekunder) | Angir maksimal transaksjonsutførelsestid |
5 | er aktiv() | Sjekker om en transaksjon er aktiv eller ikke |
6 | wasRolledBack() | Sjekker om transaksjonen rullet tilbake normalt |
7 | wasCommitted() | Sjekker om transaksjonen har forpliktet seg normalt |
8 | registerSynchronization() | Registrerer tilbakeringing for å kontrollere transaksjonen |
Viktig! Å opprette et transaksjonsobjekt og starte en transaksjon er to forskjellige ting. Her kan du tegne en analogi med Trådklassen. Når du oppretter et Thread()-objekt, starter ikke JVM en ny tråd ennå. For å starte det, må du kalle start()-metoden på Thread-objektet. Det er det samme med en transaksjon - den må kalle opp begin()-metoden.
Et eksempel på hvordan transaksjoner vanligvis håndteres i Hibernate:
Session session = sessionFactory.openSession();
Transaction transaction = session.getTransaction();
try {
transaction.begin();
Long count = session.createQuery("select count(*) from Employee", Long.class).uniqueResult();
transaction.commit();
}
catch (Exception e) {
if (transaction.getStatus() == ACTIVE || transaction.getStatus() == MARKED_ROLLBACK) {
transaction.rollback();
}
}
finally {
session.close();
sessionFactory.close();
}
Vi ser tre ting her:
Først blir alt arbeid med databasen pakket inn i en transaksjon ved å kalle metoder begin()
og commit()
Alle handlinger mellom kall til disse to metodene må utføres: enten alle sammen eller ingenting.
For det andre, hvis det oppstår en feil, prøver vi å tilbakestille transaksjonen - ring rollback()
. Dette betyr at TransactionManger først må registrere alle handlingene som var mellom begin()
og commit()
, og deretter returnere alt som det var hvis vi ringte rollback()
.
Og forresten, det er ikke et faktum at det ikke blir noen feil når du kaller tilbakerullingsmetoden. Feil skjer alltid. Du trenger bare å akseptere dette faktum og være klar for det.
4.3 Transaksjonsansvarlig
Fra et transaksjonsadministrasjonsperspektiv er Hibernate bare en lett objektinnpakning for JDBC. Hibernate i seg selv har ikke funksjoner for transaksjonsbehandling. Hibernate Transaction er faktisk en innpakning for den underliggende JDBC-transaksjonen (eller JTA-transaksjons-omslaget). JDBCTransaction er standard. Eksempel fra Hiberante-innstillingsfil:
hibernate.transaction.factory_class org.hibernate.transaction.JTATransactionFactory
hibernate.transaction.factory_class org.hibernate.transaction.JDBCTransactionFactory
La oss ta en ny titt på koden vår ved å bruke transaksjoner:
Session session = sessionFactory.openSession();
Transaction transaction = session.getTransaction();
transaction.begin();
//here is your code for working with the base
session.flush();
transaction.commit();
session.close();
La oss nå se på JDBCTransaction-klassekoden:
public class JDBCTransaction implements Transaction {
public void begin() throws HibernateException {
...
if (toggleAutoCommit) jdbcContext.connection().setAutoCommit(false);
...
}
}
Dette er metoden for å starte en transaksjon. Se deretter på sendemetoden:
public void commit() throws HibernateException {
...
jdbcContext.connection().commit();
...
jdbcContext.connection().setAutoCommit( true );
...
}
La oss nå erstatte denne koden i Hibernate-eksempelkoden:
Gå i dvale | Enkel JDBC-kode |
---|---|
|
|
Så native Hibernate-transaksjoner er bare native JDBC-anrop til databasen. Ingenting mer og intet mindre. Men JTA-transaksjoner er mer interessante. Men mer om det en annen gang.