4.1 Introducere în tranzacțiile în Hibernate

La toate cele de mai sus, aș dori să adaug informații despre tranzacții. După cum știți deja, o tranzacție este un grup de acțiuni care trebuie efectuate numai împreună . Dacă orice acțiune a eșuat sau a fost executată cu o eroare, atunci toate celelalte acțiuni trebuie să fie anulate.

Hibernate poate lucra cu două tipuri de tranzacții:

  • JDBC
  • JTA

O tranzacție JDBC este de fapt o tranzacție de bază de date. Este legat de lucrul cu baza de date, de conexiunea JDBC. Și se asigură că acțiunile atunci când lucrează cu baza de date sunt efectuate așa cum ar trebui: fie toate, fie nimic.

JTA - Tranzacția este o tranzacție la nivel de aplicație. Nu este legat de nicio bază de date. Sarcina sa este de a se asigura că anumite acțiuni sunt efectuate: fie totul, fie nimic.

De exemplu, puteți scrie date în mai multe baze de date diferite în cadrul unei singure tranzacții JTA. Apoi, dacă apare o eroare, atunci tranzacția JTA va trebui să anuleze modificările din toate bazele de date. Chiar și cele care au fost executate cu succes în ceea ce privește o anumită bază de date.

4.2 Hibernare Interfață Tranzacții

În biblioteca Hibernate, o tranzacție este reprezentată de interfața Tranzacție, care poate avea diferite implementări. De exemplu, atunci când lucrează cu Spring, Spring oferă propriul său mecanism de tranzacție JTA.

Metodele acestei interfețe sunt:

# Metodă Descriere
1 ÎNCEPE() Începe o nouă tranzacție
2 commit() Încheie tranzacția, împinge/commite toate modificările
3 rollback() Derulează înapoi tranzacția curentă
4 setTimeout(int secunde) Setează timpul maxim de executare a tranzacției
5 este activ() Verifică dacă o tranzacție este activă sau nu
6 wasRolledBack() Verifică dacă tranzacția a revenit în mod normal
7 a fost angajat() Verifică dacă tranzacția a fost efectuată în mod normal
8 registerSynchronization() Înregistrează un apel invers pentru a controla tranzacția

Important! Crearea unui obiect de tranzacție și începerea unei tranzacții sunt două lucruri diferite. Aici puteți face o analogie cu clasa Thread. Când creați un obiect Thread(), JVM-ul nu începe încă un fir nou. Pentru a-l porni, trebuie să apelați metoda start() pe obiectul Thread. Este același lucru cu o tranzacție - trebuie să apeleze metoda begin().

Un exemplu despre modul în care tranzacțiile sunt de obicei gestionate în 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();
}

Vedem trei lucruri aici:

În primul rând, toate lucrările cu baza de date sunt incluse într-o tranzacție prin apelarea metodelor begin()și commit()trebuie efectuate toate acțiunile dintre apelurile la aceste două metode: fie toate împreună, fie nimic.

În al doilea rând, dacă apare vreo eroare, încercăm să anulăm tranzacția - apelăm la rollback(). Aceasta înseamnă că TransactionManger trebuie să înregistreze mai întâi toate acțiunile care au fost între begin()și commit()și apoi să returneze totul așa cum a fost dacă am sunat rollback().

Și apropo, nu este un fapt că nu va exista nicio eroare la apelarea metodei rollback. Greșelile apar mereu. Trebuie doar să accepți acest fapt și să fii pregătit pentru el.

4.3 Manager de tranzacții

Din perspectiva managementului tranzacțiilor, Hibernate este doar un înveliș de obiecte ușor pentru JDBC. Hibernate în sine nu are caracteristici de procesare a tranzacțiilor. Hibernate Transaction este de fapt un wrapper pentru tranzacția JDBC subiacentă (sau Wrapper-ul tranzacției JTA). JDBCTransaction este implicit. Exemplu din fișierul de setări Hiberante:


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

Să aruncăm o altă privire la codul nostru folosind tranzacții:


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

Acum să ne uităm la codul clasei JDBCTransaction:


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

Aceasta este metoda de a începe o tranzacție. Apoi uită-te la metoda de trimitere:


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

Acum să înlocuim acest cod în exemplul de cod Hibernate:

Hibernează Cod JDBC simplu

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

Deci, tranzacțiile native Hibernate sunt doar apeluri JDBC native către baza de date. Nimic mai mult și nimic mai puțin. Dar tranzacțiile JTA sunt mai interesante. Dar mai multe despre asta altă dată.