Pertanyaan Transaksi NHibernate pada Pembacaan


Saya telah membaca dokumentasi dan penjelasan mengapa sangat disarankan untuk menggunakan transaksi pada operasi baca di NH. Namun, saya masih belum sepenuhnya "membeli" ke dalamnya. Dapatkah seseorang menusuk untuk menjelaskannya tanpa memberitahu saya kepada RTFM, yang sudah saya lakukan? ;)


32
2017-11-01 15:42


asal


Jawaban:


Posting ini dari salah satu penulis mungkin ada jawaban Anda:

Bahkan jika kita hanya membaca data, kami   ingin menggunakan transaksi, karena   menggunakan transaksi memastikan bahwa kita dapatkan   hasil konsisten dari database.   NHibernate berasumsi bahwa semua akses ke   database dilakukan di bawah   transaksi, dan sangat tidak disarankan   setiap penggunaan sesi tanpa   transaksi.

Mengesampingkan masalah keamanan   bekerja dengan transaksi,   asumsi bahwa transaksi adalah   mahal dan kita perlu mengoptimalkannya   yang salah. Seperti yang sudah disebutkan,   databasenya selalu berjalan   transaksi. Dan basis datanya sudah ada   sangat dioptimalkan untuk bekerja dengan   transaksi. Pertanyaannya adalah apa saja   ini per pernyataan atau per batch.   Ada beberapa jumlah pekerjaan yang dibutuhkan   harus dilakukan untuk membuat dan membuang a   transaksi, dan harus melakukannya per   Pernyataan sebenarnya lebih mahal daripada   melakukannya per batch.


23
2017-11-01 16:13



Apa yang dikatakan orang lain adalah benar, tetapi mereka tidak menunjukkan bahwa masalah dengan tidak mengontrol transaksi sendiri adalah jika Anda melakukan beberapa operasi NHibernate tanpa transaksi eksplisit, masing-masing operasi ini akan berlangsung di transaksi terpisah.

Jadi Anda dapat dengan mudah mendapatkan ketidakkonsistenan antara operasi. Dengan secara eksplisit memulai transaksi NHibernate kemudian melakukan operasi di dalamnya, Anda dijamin konsistensi di seluruh operasi ini.

Ini, tentu saja, benar untuk SETIAP lapisan akses data yang secara implisit memulai transaksi untuk Anda jika Anda tidak melakukannya. Ini tidak terbatas pada NHibernate.


8
2017-11-01 16:22



var fooIdFromDb = ExecuteQuery("Select Id from Foo where something = somethingelse");
var barsFromDb = ExecuteQuery("Select * from Bar where FooId = " + fooIdFromDB);

Bagaimana jika beberapa transaksi lain menghapus baris dari Bar di antara dua kueri? Anda akan memiliki masalah dengan data hantu. Ini bukan masalah khusus NHibernate. Anda akan memiliki masalah yang sama dengan jenis akses database lainnya tanpa menggunakan transaksi. Anda harus membaca manual tentang transaksi secara umum daripada manual NHiberante.


6
2017-11-01 16:05



Mari fokus pada apa yang terjadi jika Anda mau tidak gunakan transaksi. Ini adalah kebiasaan, tetapi tidak wajib, bahwa Anda menutup Sesi di akhir pemrosesan, tetapi sebelum Anda mulai membaca data (yaitu, Tampilan). Metode ini disebarkan di bawah istilah "Buka Sesi dalam Tampilan"(meskipun jelas memiliki pola untuk mencegah membaca sebelum ditutup). Pola ini sering digunakan dalam aplikasi web di mana sesi dibuka ketika permintaan tiba dan ditutup tepat sebelum menulis ke aliran respons.

(N) Hibernate membutuhkan sesi dan transaksi. Ketika Anda membaca tanpa menggunakan transaksi eksplisit, transaksi akan diatur untuk Anda. Ketika Anda membaca setelah transaksi dilakukan, perilaku tergantung pada konfigurasi dan driver NH.

Baik ODBC dan JDBC tidak mendefinisikan apa yang terjadi ketika koneksi ditutup dan ada data tidak terikat atau tidak terkendali. Ketika koneksi dibuka kembali, ada kemungkinan bahwa transaksi baru secara otomatis dimulai.

Menggunakan akses non-transaksional hanya dapat digunakan bersama dengan pengaturan auto-commit secara eksplisit dalam konfigurasi NHibernate. Jika tidak, default driver digunakan dan dapat berfungsi, atau mungkin tidak berfungsi.

Singkatnya, ada banyak kekurangan dan perilaku tidak terdefinisi ketika Anda tidak menggunakan transaksi saat membaca. Ini akan sering berfungsi, tetapi ini tergantung pada konfigurasi, pola yang diterapkan, driver. Ada kemungkinan besar Anda dapatkan LazyInitializationExceptions, yang merupakan hasil umum dari membaca setelah melakukan tanpa membuka transaksi baru.

"Praktik terbaik" adalah menggunakan satu transaksi untuk baca / tulis dan satu lagi untuk hanya-baca. Ini dijelaskan secara singkat di tautan sebelumnya, bagian "Dapatkah saya menggunakan dua transaksi dalam satu sesi" tetapi membutuhkan lebih banyak implementasi Anda.

Tidak hanya "menggunakan transaksi untuk dibaca", itu juga: "gunakan transaksi yang sama yang Anda gunakan untuk menulis untuk membaca". (dan kemudian, sementara ini benar, aplikasi yang sebenarnya akan bergantung pada pola Anda saat ini, berapa banyak tingkatan yang ada, caching dan konfigurasi).

Memperbarui: sedikit diperluas, menghapus beberapa ambiguitas


5
2017-11-01 16:32



juga:
Tidak menggunakan transaksi eksplisit memiliki efek membatalkan cache tingkat ke-2.


3
2017-11-01 16:31