4.1 Pengenalan kepada transaksi dalam Hibernate

Kepada semua perkara di atas, saya ingin menambah maklumat tentang transaksi. Seperti yang anda sedia maklum, urus niaga ialah sekumpulan tindakan yang mesti dilakukan bersama-sama sahaja . Jika sebarang tindakan gagal atau telah dilaksanakan dengan ralat, maka semua tindakan lain mesti dibatalkan.

Hibernate dapat berfungsi dengan dua jenis transaksi:

  • JDBC
  • JTA

Transaksi JDBC sebenarnya adalah transaksi pangkalan data. Ia terikat untuk bekerja dengan pangkalan data, dengan sambungan JDBC. Dan dia memastikan bahawa tindakan semasa bekerja dengan pangkalan data dilakukan seperti yang sepatutnya: sama ada semua atau tidak.

JTA - Transaksi ialah transaksi peringkat aplikasi. Ia tidak terikat dengan mana-mana pangkalan data. Tugasnya adalah untuk memastikan bahawa tindakan tertentu dilakukan: sama ada semua atau tidak.

Sebagai contoh, anda boleh menulis data ke beberapa pangkalan data yang berbeza dalam satu transaksi JTA. Kemudian jika ralat berlaku, maka transaksi JTA perlu melancarkan semula perubahan dalam semua pangkalan data. Malah yang telah dilaksanakan dengan jayanya dari segi pangkalan data tertentu.

4.2 Antara Muka Transaksi Hibernate

Dalam pustaka Hibernate, transaksi diwakili oleh antara muka Transaksi, yang boleh mempunyai pelaksanaan yang berbeza. Sebagai contoh, apabila bekerja dengan Spring, Spring menyediakan mekanisme transaksi JTAnya sendiri.

Kaedah antara muka ini ialah:

# Kaedah Penerangan
1 mula () Memulakan transaksi baharu
2 commit() Menamatkan transaksi, menolak/melakukan semua perubahan
3 kembalikan() Menggulung semula urus niaga semasa
4 setTimeout(int saat) Menetapkan masa pelaksanaan transaksi maksimum
5 adalah aktif() Semak sama ada transaksi aktif atau tidak
6 wasRolledBack() Menyemak sama ada urus niaga itu kembali seperti biasa
7 wasCommitted() Semak sama ada transaksi telah dilakukan seperti biasa
8 registerSynchronization() Mendaftarkan panggilan balik untuk mengawal transaksi

Penting! Mencipta objek transaksi dan memulakan transaksi adalah dua perkara yang berbeza. Di sini anda boleh melukis analogi dengan kelas Thread. Apabila anda mencipta objek Thread(), JVM belum memulakan utas baharu lagi. Untuk memulakannya, anda perlu memanggil kaedah start() pada objek Thread. Ia sama dengan transaksi - ia perlu memanggil kaedah begin().

Contoh cara urus niaga biasanya dikendalikan dalam 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();
}

Kami melihat tiga perkara di sini:

Pertama, semua kerja dengan pangkalan data dibungkus dalam urus niaga dengan memanggil kaedah begin()dan commit()Semua tindakan antara panggilan ke dua kaedah ini mesti dilakukan: sama ada semuanya bersama-sama, atau tiada apa-apa.

Kedua, jika sebarang ralat berlaku, kami cuba tarik balik transaksi - panggil rollback(). Ini bermakna TransactionManger mesti merekodkan semua tindakan yang berada di antara begin()dan commit(), dan kemudian mengembalikan semuanya seperti yang kami hubungi rollback().

Dan dengan cara ini, ia bukan fakta bahawa tidak akan ada ralat semasa memanggil kaedah rollback. Kesilapan selalu berlaku. Anda hanya perlu menerima hakikat ini dan bersedia untuknya.

4.3 Pengurus urus niaga

Dari perspektif pengurusan transaksi, Hibernate hanyalah pembungkus objek ringan untuk JDBC. Hibernate sendiri tidak mempunyai ciri pemprosesan transaksi. Transaksi Hibernate sebenarnya adalah pembungkus untuk transaksi JDBC yang mendasari (atau pembungkus transaksi JTA). JDBCTransaction ialah lalai. Contoh daripada fail tetapan Hiberante:


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

Mari kita lihat lagi kod kami menggunakan transaksi:


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

Sekarang mari kita lihat kod kelas JDBCTransaction:


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

Ini adalah kaedah untuk memulakan transaksi. Kemudian lihat kaedah hantar:


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

Sekarang mari kita gantikan kod ini ke dalam kod contoh Hibernate:

Hibernate Kod JDBC mudah

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

Jadi transaksi Hibernate asli hanyalah panggilan JDBC asli ke pangkalan data. Tidak lebih dan tidak kurang. Tetapi transaksi JTA lebih menarik. Tetapi lebih lanjut mengenai itu lain kali.