4.1 Introduktion till transaktioner i Hibernate

Till allt ovanstående skulle jag vilja lägga till information om transaktioner. Som du redan vet är en transaktion en grupp av åtgärder som endast måste utföras tillsammans . Om någon åtgärd misslyckades eller utfördes med ett fel måste alla andra åtgärder avbrytas.

Hibernate kan arbeta med två typer av transaktioner:

  • JDBC
  • JTA

En JDBC-transaktion är faktiskt en databastransaktion. Den är knuten till att arbeta med databasen, till JDBC-anslutningen. Och han ser till att åtgärderna när man arbetar med databasen utförs som de ska: antingen allt eller inget.

JTA - Transaktion är en transaktion på applikationsnivå. Den är inte knuten till någon databas. Dess uppgift är att se till att vissa åtgärder utförs: antingen allt eller inget.

Du kan till exempel skriva data till flera olika databaser inom en enda JTA-transaktion. Om ett fel uppstår, måste JTA-transaktionen återställa ändringarna i alla databaser. Även de som kördes framgångsrikt i form av en viss databas.

4.2 Viloläge Transaktionsgränssnitt

I Hibernate-biblioteket representeras en transaktion av Transaction-gränssnittet, som kan ha olika implementeringar. Till exempel, när du arbetar med Spring, tillhandahåller Spring sin egen JTA-transaktionsmekanism.

Metoderna för detta gränssnitt är:

# Metod Beskrivning
1 Börja() Startar en ny transaktion
2 begå() Avslutar transaktionen, pushar/besluter alla ändringar
3 rulla tillbaka() Återställer den aktuella transaktionen
4 setTimeout (intsekunder) Ställer in den maximala transaktionsexekveringstiden
5 är aktiv() Kontrollerar om en transaktion är aktiv eller inte
6 wasRolledBack() Kontrollerar om transaktionen rullade tillbaka normalt
7 wasCommitted() Kontrollerar om transaktionen har genomförts normalt
8 registerSynchronization() Registrerar en återuppringning för att kontrollera transaktionen

Viktig! Att skapa ett transaktionsobjekt och starta en transaktion är två olika saker. Här kan du dra en analogi med trådklassen. När du skapar ett Thread()-objekt startar JVM inte en ny tråd ännu. För att starta det måste du anropa start()-metoden på Thread-objektet. Det är samma sak med en transaktion - den måste anropa metoden begin().

Ett exempel på hur transaktioner vanligtvis hanteras 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 saker här:

Först, allt arbete med databasen lindas in i en transaktion genom anropsmetoder begin()och commit()Alla åtgärder mellan anrop till dessa två metoder måste utföras: antingen alla tillsammans eller ingenting.

För det andra, om något fel uppstår, försöker vi återställa transaktionen - ring rollback(). Det betyder att TransactionManger först måste registrera alla åtgärder som var mellan begin()och commit()och sedan returnera allt som det var om vi ringde rollback().

Och förresten, det är inte ett faktum att det inte blir något fel när man anropar återställningsmetoden. Det händer alltid misstag. Du behöver bara acceptera detta faktum och vara redo för det.

4.3 Transaktionsansvarig

Ur ett transaktionshanteringsperspektiv är Hibernate bara en lättviktsobjektomslag för JDBC. Hibernate i sig har inga transaktionsbearbetningsfunktioner. Hibernate Transaction är faktiskt ett omslag för den underliggande JDBC-transaktionen (eller JTA-transaktionsomslaget). JDBCTransaction är standard. Exempel från Hiberante-inställningsfil:


hibernate.transaction.factory_class  org.hibernate.transaction.JTATransactionFactory
hibernate.transaction.factory_class  org.hibernate.transaction.JDBCTransactionFactory

Låt oss ta en ny titt på vår kod med hjälp av transaktioner:


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();

Låt oss nu titta på JDBCTransaction-klasskoden:


public class JDBCTransaction implements Transaction {
 
    public void begin() throws HibernateException {
    	...
    	if (toggleAutoCommit) jdbcContext.connection().setAutoCommit(false);
    	...
    }
}

Detta är metoden för att starta en transaktion. Titta sedan på sändningsmetoden:


public void commit() throws HibernateException {
    ...
    jdbcContext.connection().commit();
    ...
    jdbcContext.connection().setAutoCommit( true );
    ...
}

Låt oss nu ersätta denna kod i Hibernate-exempelkoden:

Övervintra Enkel JDBC-kod

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å inbyggda Hibernate-transaktioner är bara inbyggda JDBC-anrop till databasen. Inget mer och inget mindre. Men JTA-transaktioner är mer intressanta. Men mer om det en annan gång.