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.

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

Session session = sessionFactory.openSession();
Transaction transaction = session.getTransaction();
transaction.begin();
//here is your code for working with the database
session.flush();
transaction.commit();
session.close();

Connection conn = jdbcContext.connection();
conn.setAutoCommit(false);
 
//here is your database code
conn.commit ()
conn.setAutoCommit(true);
conn.close();

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.