Mengapa saya memerlukan Transaksi dalam mode Hibernasi untuk operasi hanya baca?
Apakah transaksi berikut mengunci DB?
Contoh kode untuk diambil dari DB:
Transaction tx = HibernateUtil.getCurrentSession().beginTransaction(); // why begin transaction?
//readonly operation here
tx.commit() // why tx.commit? I don't want to write anything
Bisakah saya menggunakan session.close()
sebagai pengganti tx.commit()
?
java
database
hibernate
transactions
database-connection
pengguna93796
sumber
sumber
Jawaban:
Anda mungkin sebenarnya memiliki alasan untuk menandai transaksi sebagai hanya baca.
autocommit=true
jika opsi berbeda tidak ditetapkan secara eksplisit.@Transactional(readonly=true)
, Spring akan mengatur transaksi JDBC ke mode hanya-baca, sehingga Anda akan menentukan apakah itu benar - benar mungkin untuk menulis ke dalam DB dalam lingkup transaksi ini. Jika arsitektur Anda rumit dan beberapa anggota tim mungkin memilih untuk meletakkan kueri modifikasi di tempat yang tidak diharapkan, tanda ini akan mengarahkan Anda ke tempat yang bermasalah.Singkatnya - Anda bisa pergi dua arah, tetapi Anda perlu memahami konsekuensinya.
sumber
Semua pernyataan database dijalankan dalam konteks transaksi fisik, bahkan ketika kami tidak secara eksplisit menyatakan batasan transaksi (BEGIN / COMMIT / ROLLBACK).
Jika Anda tidak mendeklarasikan batasan transaksi secara eksplisit, maka setiap pernyataan harus dieksekusi dalam transaksi terpisah (
autocommit
mode) terpisah. Ini bahkan dapat menyebabkan membuka dan menutup satu koneksi per pernyataan kecuali lingkungan Anda dapat menangani pengikatan koneksi-per-utas.Menyatakan layanan sebagai
@Transactional
akan memberi Anda satu koneksi untuk seluruh durasi transaksi, dan semua pernyataan akan menggunakan koneksi isolasi tunggal tersebut. Ini jauh lebih baik daripada tidak menggunakan transaksi eksplisit sejak awal.Pada aplikasi besar, Anda mungkin memiliki banyak permintaan bersamaan, dan mengurangi tingkat permintaan akuisisi koneksi database pasti akan meningkatkan kinerja aplikasi Anda secara keseluruhan.
JPA tidak memberlakukan transaksi pada operasi baca. Hanya operasi tulis yang akhirnya memunculkan pengecualian yang diperlukan transaksi jika Anda lupa memulai konteks transaksional. Namun demikian, selalu lebih baik untuk menyatakan batas transaksi bahkan untuk transaksi hanya-baca (di Spring
@Transactional
memungkinkan Anda menandai transaksi hanya-baca, yang memiliki manfaat kinerja yang hebat).sumber
Transaksi memang mengunci database - mesin database yang baik menangani kunci bersamaan dengan cara yang masuk akal - dan berguna dengan penggunaan hanya-baca untuk memastikan bahwa tidak ada yang lain. transaksi menambahkan data yang membuat tampilan Anda tidak konsisten. Anda selalu menginginkan transaksi (meskipun kadang-kadang masuk akal untuk menyesuaikan tingkat isolasi, sebaiknya jangan lakukan itu sejak awal); jika Anda tidak pernah menulis ke DB selama transaksi Anda, baik melakukan maupun mengembalikan transaksi akan sama (dan sangat murah).
Sekarang, jika Anda beruntung dan kueri Anda terhadap DB sedemikian rupa sehingga ORM selalu memetakannya ke kueri SQL tunggal, Anda dapat lolos tanpa transaksi eksplisit , mengandalkan perilaku autocommit bawaan DB, tetapi ORM adalah sistem yang relatif kompleks jadi sama sekali tidak aman untuk mengandalkan perilaku seperti itu kecuali jika Anda bekerja lebih keras untuk memeriksa apa yang sebenarnya dilakukan oleh implementasi. Menulis batas transaksi eksplisit jauh lebih mudah untuk dilakukan dengan benar (terutama jika Anda dapat melakukannya dengan AOP atau teknik serupa yang digerakkan ORM; dari Java 7 dan seterusnya coba-dengan-sumber daya dapat digunakan juga, saya kira).
sumber
Tidak masalah apakah Anda hanya membaca atau tidak - database harus tetap melacak kumpulan hasil Anda, karena klien database lain mungkin ingin menulis data yang akan mengubah kumpulan hasil Anda.
Saya telah melihat program yang salah untuk membunuh sistem database yang besar, karena mereka hanya membaca data, tetapi tidak pernah melakukan, memaksa log transaksi untuk berkembang, karena DB tidak dapat merilis data transaksi sebelum COMMIT atau ROLLBACK, bahkan jika klien tidak melakukan apa pun selama berjam-jam.
sumber