Transakcje

Dostępny

4.1 Wprowadzenie do transakcji w Hibernate

Do wszystkich powyższych chciałbym dodać informacje o transakcjach. Jak już wiesz, transakcja to grupa czynności, które muszą być wykonane tylko razem . Jeśli jakakolwiek akcja nie powiodła się lub została wykonana z błędem, wszystkie inne akcje muszą zostać anulowane.

Hibernate może pracować z dwoma typami transakcji:

  • JDBC
  • JTA

Transakcja JDBC jest właściwie transakcją bazy danych. Jest to związane z pracą z bazą danych, z połączeniem JDBC. I pilnuje, aby działania podczas pracy z bazą danych były wykonywane tak, jak powinny: albo wszystko, albo nic.

JTA — transakcja jest transakcją na poziomie aplikacji. Nie jest powiązany z żadną bazą danych. Jego zadaniem jest zapewnienie wykonania określonych działań: albo wszystko, albo nic.

Na przykład możesz zapisać dane do kilku różnych baz danych w ramach jednej transakcji JTA. Wtedy, jeśli wystąpi błąd, transakcja JTA będzie musiała cofnąć zmiany we wszystkich bazach danych. Nawet te, które zostały pomyślnie wykonane pod względem konkretnej bazy danych.

4.2 Interfejs transakcji Hibernate

W bibliotece Hibernate transakcja jest reprezentowana przez interfejs Transaction, który może mieć różne implementacje. Na przykład, pracując ze Springiem, Spring zapewnia własny mechanizm transakcyjny JTA.

Metody tego interfejsu to:

# metoda Opis
1 zaczynać() Rozpoczyna nową transakcję
2 popełniać() Kończy transakcję, wypycha/zatwierdza wszystkie zmiany
3 wycofanie() Wycofuje bieżącą transakcję
4 setTimeout(int sekundy) Ustawia maksymalny czas realizacji transakcji
5 jest aktywny() Sprawdza, czy transakcja jest aktywna, czy nie
6 było cofnięte() Sprawdza, czy transakcja została wycofana normalnie
7 był zaangażowany() Sprawdza, czy transakcja została zatwierdzona normalnie
8 zarejestrujSynchronizacja() Rejestruje wywołanie zwrotne w celu kontrolowania transakcji

Ważny! Tworzenie obiektu transakcji i rozpoczynanie transakcji to dwie różne rzeczy. Tutaj możesz narysować analogię z klasą Thread. Podczas tworzenia obiektu Thread() JVM nie uruchamia jeszcze nowego wątku. Aby go uruchomić, należy wywołać metodę start() na obiekcie Thread. Tak samo jest z transakcją - musi ona wywołać metodę begin().

Przykład tego, jak zwykle obsługiwane są transakcje w 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();
}

Widzimy tutaj trzy rzeczy:

Po pierwsze, cała praca z bazą danych jest opakowana w transakcję poprzez wywołanie metod begin()i commit()Wszystkie akcje pomiędzy wywołaniami tych dwóch metod muszą zostać wykonane: albo wszystkie razem, albo nic.

Po drugie, jeśli wystąpi jakikolwiek błąd, staramy się wycofać transakcję - wywołujemy metodę rollback(). Oznacza to, że TransactionManger musi najpierw zarejestrować wszystkie akcje, które były między begin()i commit(), a następnie zwrócić wszystko tak, jak to było, gdybyśmy wywołali rollback().

A tak przy okazji, nie jest faktem, że przy wywołaniu metody rollback nie wystąpi żaden błąd. Błędy zawsze się zdarzają. Trzeba tylko zaakceptować ten fakt i być na to gotowym.

4.3 Menedżer transakcji

Z perspektywy zarządzania transakcjami, Hibernate jest po prostu lekkim opakowaniem obiektów dla JDBC. Sam Hibernate nie ma funkcji przetwarzania transakcji. Hibernate Transaction jest w rzeczywistości opakowaniem podstawowej transakcji JDBC (lub opakowaniem transakcji JTA). Wartość domyślna to JDBCTransaction. Przykład z pliku ustawień Hiberante:

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

Przyjrzyjmy się jeszcze raz naszemu kodowi za pomocą transakcji:

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

Teraz spójrzmy na kod klasy JDBCTransaction:

public class JDBCTransaction implements Transaction {

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

Jest to metoda rozpoczęcia transakcji. Następnie spójrz na metodę wysyłania:

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

Teraz zastąpmy ten kod przykładowym kodem Hibernate:

Hibernować Prosty kod JDBC

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

Tak więc natywne transakcje Hibernate są po prostu natywnymi wywołaniami JDBC do bazy danych. Nic więcej i nic mniej. Ale transakcje JTA są bardziej interesujące. Ale o tym innym razem.

Komentarze
  • Popularne
  • Najnowsze
  • Najstarsze
Musisz się zalogować, aby dodać komentarz
Ta strona nie ma jeszcze żadnych komentarzy