Penelitian utama dalam artikel ini adalah Sesi Hibernate dan tingkat isolasi. Pendahuluan dan contoh spesifik adalah sebagai berikut.
Mari kita lihat beberapa konsep terlebih dahulu:
1. Bacaan Kotor: Bacaan kotor juga disebut pembacaan data yang tidak valid. Ini berarti bahwa selama akses database, hal T1 memodifikasi nilai tertentu, dan kemudian hal T2 membaca nilainya. Setelah itu, T1 membatalkan modifikasi nilai karena beberapa alasan, yang menyebabkan data dibaca oleh T2 menjadi tidak valid. Bacaan kotor berarti bahwa ketika sesuatu mengakses data dan memodifikasi data, dan modifikasi ini belum diserahkan ke database, hal lain juga mengakses data ini dan kemudian menggunakan data ini. Karena data ini masih belum diserahkan, data yang dibaca oleh hal lain adalah data kotor, dan operasi yang dilakukan berdasarkan data kotor salah.
2. Tidak berulang -ulang membaca: Misalnya, ketika saya membaca posting, data yang saya temukan adalah Zhang San dan Li Si. Kemudian, setelah saya segar, saya menemukan bahwa Zhang San awal menjadi Zhang Ba. Ini adalah apa yang disebut bacaan yang tidak dapat diulang, karena data yang saya baca tidak diulangi.
3. Bacaan Fantasi: Ketika saya mencari data, saya mulai menemukan 3 catatan. Ketika saya menyegarkannya, saya menemukan bahwa catatan menjadi 8. Ini adalah pembacaan fantasi.
4. Kirim Bacaan: Anda hanya dapat membaca setelah dikirim. Oracle default untuk ini. Tidak ada bacaan kotor dengan cara ini.
5. Pengulangan: Jelas kebalikan dari bacaan yang tidak dapat diulang. Ini dapat menghindari pembacaan yang tidak dapat diulang, tetapi ini tidak dapat menghindari pembacaan hantu.
6. Serialisasi: Metode ini sangat ketat. Dalam istilah awam, ketika saya melakukan sesuatu, tidak ada orang lain yang bisa melakukannya. Ini sangat aman, tapi sangat tidak efisien.
Di bawah ini kami menggunakan contoh -contoh praktis untuk memahami penerapan izin cache hibernate.
Hibernate Mapping Database terkait dengan strategi pembuatan kunci utama.
Contoh menghasilkan kunci primer di UUID:
Pengguna Kelas Publik {Private String UID; Private String Uname; Private Date Birthday; Public String getuid () {return uid;} public void public setUid (string uid) {this.uid = uid;} string publik getUname () {return uname;} public void setuname (string uname) {this.uname = {{} public; setBirthday (tanggal ulang tahun) {this.birthday = ulang tahun;}}User.hbm.xml:
<? XML Versi = "1.0"?> <! Doctype Hibernate-Mapping Public "-// Hibernate/Hibernate Mapping DTD 3.0 // EN" "http://hibernate.sourceForge.net/hibernate-papping-3.0.dtd"> <!-Paket nama paket dari paket dari paket dari paket classion- 3.0.dtd "> <! package = "com.lixue.bean"> <!-Nama node kelas mewakili nama kelas entitas, dan tabel mewakili nama entitas yang dipetakan ke tabel dalam database-> <class name = "user" tabel = "t_user"> <id name = "uid"> <! name = "ulang tahun"/> </slass> </hibernate-Mapping>
Metode Uji:
/ ***Uji strategi pembuatan kunci utama UUID*/ public void testSave1 () {/*Sesi dan hal -hal yang ditentukan*/ sesi sesi = null; Transaksi transaksi = null; coba { /*dapatkan sesi dan hal* / sesi = hibernateutils.getSession (); transaksi = session.begintransaction (); /*Buat pengguna*/ pengguna pengguna = pengguna baru (); user.setuname ("xi jinping"); user.setBirthday (tanggal baru ()); / *** Karena strategi pembuatan kunci utama pengguna adalah UUID, setelah menelepon Save, itu hanya termasuk pengguna dalam manajemen sesi* Pernyataan insert tidak akan dikeluarkan, tetapi ID telah dihasilkan, dan status keberadaan yang ada di persistenceContext adalah false*/ session.save (pengguna); /** * Calling flush, Hibernate will clean up the cache (insert the objects in the temporary collection in session->insertions into the database, clearing the temporary collection) * At this time, the data cannot be seen in the database, but if the isolation level of the database is set to not submitted to read, * Then we can see the flushed data, and the existencesInDatabase status in PersistenceContext is true */ session.flush (); /** * Kirim hal * Secara default, operasi komit akan melakukan cache pembersihan flush, * Jadi data tidak dapat digulung kembali setelah memanggil flush tanpa tampilan * commit * transaction.commit (); } catch (Exception e) {E.PrintStackTrace (); transaction.rollback (); } akhirnya {hibernateutils.closesession (sesi); }} Kami dapat men -debug program melalui breakpoints:
1. Karena laju samping generasi kunci utama pengguna adalah UUID, setelah memanggil metode save (), objek pengguna hanya dapat dimasukkan dalam manajemen sesi, dan pernyataan insert tidak akan dikeluarkan, tetapi ID telah dihasilkan (Catatan: dua tempat sangat penting setelah disimpan. PersistenceContext-> EntityEntries-> MAP-> TABLE-> Elemen Array tertentu-> Nilai menyimpan objek. Seperti yang ditunjukkan pada gambar:
2. Setelah memanggil metode flush (), nilai yang tersimpan sementara dari ActionQueue dalam sesi akan dihapus, dan kemudian nilai ada di dalam persistenceContext diatur ke true, menunjukkan bahwa ada data yang sesuai dalam database yang harus dibaca, tetapi ketika membuka database dan membuka tabel, Anda tidak dapat melihat data, karena level yang default, tetapi ketika membuka database dan membuka tabel, Anda tidak dapat melihat data, karena level yang default, tetapi ketika membuka database dan membuka tabel, Anda tidak dapat melihat data, karena level yang default, tetapi ketika saya membuka database dan membuka tabel, Anda tidak dapat melihat data, karena level yang default, tetapi ketika saya membuka database dan membuka tabel, Anda tidak dapat melihat data, karena level yang default, tetapi ketika saya membuka database, data. Setelah memanggil metode komit (), ada data dalam database.
Contoh menghasilkan kunci primer dengan cara asli:
Public Class User1 {Private Integer UID; Private String Uname; Tanggal Private Date; Public Integer GetUID () {return uid;} public void setUid (integer uid) {this.uid = uid;} public getUname () {return uname;} public void setuname (string uname) {this. ulang tahun;} public void setBirthday (tanggal ulang tahun) {this.birthday = ulang tahun;}}User1.hbm.xml:
<? XML Versi = "1.0"?> <! Doctype Hibernate-Mapping Public "-// Hibernate/Hibernate Mapping DTD 3.0 // EN" "http://hibernate.sourceForge.net/hibernate-papping-3.0.dtd"> <!-Paket nama paket dari paket dari paket dari paket classion- 3.0.dtd "> <! package = "com.lixue.bean"> <!-Nama simpul kelas mewakili nama kelas entitas (ingat untuk memodifikasi nama kelas saat menetapkan file pemetaan, jika tidak bug akan terjadi), tabel mewakili nama entitas yang dipetakan ke tabel/</u name <! <name properti = "uname"/> <name properti = "ulang tahun"/> </class> </hibernate-mapping>
Metode Uji:
/ ***menguji strategi pembuatan kunci utama asli*/ public void testSave2 () {/*Sesi dan hal -hal yang ditentukan*/ sesi sesi = null; Transaksi transaksi = null; coba { /*dapatkan sesi dan hal* / sesi = hibernateutils.getSession (); transaksi = session.begintransaction (); /*Buat pengguna*/ user1 user = new user1 (); user.setuname ("Li Keqiang"); user.setBirthday (tanggal baru ()); / *** Karena strategi pembuatan kunci utama USER1 adalah asli, setelah panggilan sesi. transaction.commit (); } catch (Exception e) {E.PrintStackTrace (); transaction.rollback (); } akhirnya {hibernateutils.closesession (sesi); }} Debug program melalui breakpoint:
1. Karena strategi pembuatan kunci utama adalah asli, setelah memanggil metode save (), pernyataan insert akan dijalankan, dan data dalam objek pengumpulan sementara akan dihapus, dan ID yang dihasilkan oleh database akan dikembalikan.
2. Sertakan objek ke dalam manajemen sesi, memodifikasi properti yang ada di persistenceContext menjadi true (menunjukkan bahwa ada data yang sesuai dalam database, tetapi tidak dapat dilihat karena area isolasi).
Mari kita uji metode hibernate lain, yang digusur (), yang berarti mengeluarkan objek dari sesi.
Untuk program yang menghasilkan strategi kunci utama UUID, berikut adalah metode pengujian:
/ ***Uji strategi pembuatan kunci utama UUID*/ public void testSave3 () {/*Sesi dan hal -hal yang ditentukan*/ sesi sesi = null; Transaksi transaksi = null; coba { /*dapatkan sesi dan hal* / sesi = hibernateutils.getSession (); transaksi = session.begintransaction (); /*Buat pengguna*/ pengguna pengguna = pengguna baru (); user.setuname ("hu jintao"); user.setBirthday (tanggal baru ()); /*** Karena strategi pembuatan kunci utama pengguna adalah UUID, setelah menelepon Simpan, hanya memasukkan pengguna ke dalam manajemen sesi* tidak akan mengeluarkan pernyataan insert, tetapi ID telah dihasilkan. Status existsIndatebase dalam sesi false */ session.save (pengguna); /*Penggusikan objek pengguna dari sesi, yaitu, dikeluarkan dari properti entitas ATTITYEnTries dari persistenceContext*/ session.evict (pengguna); /** * tidak dapat berhasil mengirimkan, karena ketika hibernasi membersihkan cache, objek pengguna dikeluarkan dari sesi memasukkan koleksi sementara untuk dimasukkan * Setelah operasi, keberadaan yang ada di properti entitas yang tidak dapat diperbarui, dan kami sebut sebagai orang yang tidak dapat diatasi, dan orang -orang yang tidak dapat diatasi, yang tidak dapat diatasi, dan ada yang ada di dalamnya, sehingga ada yang ada, sehingga ada yang ada di dalam sesi, sehingga ada yang ada, dan yang ada di atas, jadi ada yang ada, dan orang -orang yang tidak dapat diatasi, dan tidak ada yang ada di atas, sehingga keberadaannya, dan ada yang ada di atas, jadi ada yang ada, dan mereka akan melakukan apa pun yang ada di atas, sehingga ada. transaction.commit (); } catch (Exception e) {E.PrintStackTrace (); transaction.rollback (); } akhirnya {hibernateutils.closesession (sesi); }} Debugging melalui breakpoints:
1. Karena strategi generasi kunci utama UUID digunakan, pernyataan insert tidak akan dikirim setelah memanggil metode save (). Objek tersebut termasuk dalam manajemen sesi. ID telah dihasilkan dan tidak ada data yang sesuai dalam database (yaitu, nilai atribut yang ada salah adalah salah).
2. Setelah menelepon extic (), mengeluarkan objek pengguna dari sesi, yaitu, diusir dari properti entitas yang datang dari persistenceContext.
3. Ketika saya memanggil metode komit () lagi, kami akan menemukan bahwa data kami tidak dapat disimpan karena pada awalnya keberadaan kami properti indatabase salah, yaitu, tidak ada data yang sesuai dalam database. Kemudian kami memanggil Evil () untuk menghapus semua properti objek di PersistenceContext (properti keberadaannyaindatabase juga disertakan), tetapi data yang disimpan sementara di ActionQueue belum dihapus. Ketika kita memanggil metode komit (), pertama -tama kita akan secara implisit memanggil metode flush (). Fungsi metode ini juga telah disebutkan sebelumnya. Ini akan memasukkan objek sementara di ActionQueue, dan kemudian mengatur nilai properti yang ada di dalam persistenceContext ke True. Sayangnya, tidak ada properti yang ada di persistenceContext, sehingga kesalahan akan terjadi, yang mengakibatkan ketidakmampuan untuk menyimpan.
Untuk melakukan ini, kami meningkatkan prosedur di atas:
/ ***Uji strategi pembuatan kunci utama UUID*/ public void testSave4 () {/*Sesi dan hal -hal yang ditentukan*/ sesi sesi = null; Transaksi transaksi = null; coba { /*dapatkan sesi dan hal* / sesi = hibernateutils.getSession (); transaksi = session.begintransaction (); /*Buat pengguna*/ pengguna pengguna = pengguna baru (); user.setuname ("hu jintao"); user.setBirthday (tanggal baru ()); /*** Karena strategi pembuatan kunci utama pengguna adalah UUID, setelah menelepon Simpan, hanya memasukkan pengguna ke dalam manajemen sesi* tidak akan mengeluarkan pernyataan insert, tetapi ID telah dihasilkan. Status keberadaan ExistenceInbase di persistenceContext adalah false */ session.save (pengguna); / ***Setelah flush, hibernate akan membersihkan cache, menyimpan objek pengguna ke database, hapus objek pengguna dalam penyisipan di sesi*, dan atur status existsindatabase di persistenceContext ke true*/ session.flush (); / * Mengusir objek pengguna dari sesi, yaitu, dikeluarkan dari properti entityentries dari persistenceContext */ session.evict (pengguna); / *** Dapat berhasil dikirimkan karena Hibernate tidak dapat berada dalam koleksi penyisipan sesi saat membersihkan cache* Objek pengguna ditemukan (dibersihkan ketika flush dipanggil), sehingga pernyataan insert tidak akan dikeluarkan, atau status yang ada dalam sesi tidak akan diperbarui*/ transaksi.commit (); } catch (Exception e) {E.PrintStackTrace (); transaction.rollback (); } akhirnya {hibernateutils.closesession (sesi); }} CATATAN: Setelah menabung, kami memanggil metode flush () dan kemudian memanggil metode EXICT () setelah program yang dimodifikasi.
Debugging melalui breakpoints:
1. Karena masih merupakan strategi generasi UUID, setelah menelepon Save, pernyataan insert tidak akan dikeluarkan, tetapi objek tersebut termasuk dalam manajemen sesi. Properti yang ada di persistenceContext adalah salah.
2. Setelah menelepon save (), kami memanggil metode flush () lagi. Fungsi metode ini adalah untuk membersihkan cache, yaitu, mengeluarkan pernyataan insert, memasukkan objek sementara dalam penyisipan dalam sesi ke dalam database, kemudian hapus koleksi sementara, dan atur properti yang ada di properti persistenceContext ke True.
3. Setelah memanggil flush (), metode Excic () dipanggil. Fungsinya adalah untuk menghapus objek pengguna dari sesi, yaitu untuk menghapus properti Entityentries dari persistenceContext.
4. Setelah memanggil metode Ext (), metode komit () akan secara implisit memanggil metode flush () terlebih dahulu. Fungsi flush adalah untuk menghapus cache, yaitu, masukkan objek dalam sesi-> penyisipan koleksi sementara ke dalam database, tetapi kami telah memanggil metode flush () sebelumnya (Catatan: Setelah memanggil metode ini, koleksi sementara akan dibersihkan), sehingga koleksi sementara tidak memiliki objek sama sekali, sehingga pernyataan insert tidak akan dikeluarkan. Ini tidak akan memperbarui status yang ada di status di persistenceContext. Kirim dengan sukses.
Mari kita pertimbangkan untuk menggunakan metode Excic () dalam strategi generasi kunci primer asli:
/ ***menguji strategi pembuatan kunci utama asli*/ public void testSave5 () {/*Sesi dan hal -hal yang ditentukan*/ sesi sesi = null; Transaksi transaksi = null; coba { /*dapatkan sesi dan hal* / sesi = hibernateutils.getSession (); transaksi = session.begintransaction (); /*Buat pengguna*/ user1 user = new user1 (); user.setuname ("ma ying-jeou"); user.setBirthday (tanggal baru ()); / *** Karena strategi pembuatan kunci utama USER1 adalah asli, setelah menelepon session.save (), pernyataan insert akan dieksekusi,* mengembalikan ID yang dihasilkan oleh database, termasuk dalam manajemen sesi, memodifikasi status keberadaannya dalam Sesi untuk tidak dibaca, dan menghapus set sementara* jika disimpan. /* Mengusir objek pengguna dari sesi, yaitu, diusir dari properti entityentries dari persistenceContext*/ session.evict (pengguna); / *** Dapat berhasil dikirimkan karena Hibernate ada dalam koleksi penyisipan sesi saat membersihkan cache* Objek pengguna tidak dapat ditemukan, sehingga pernyataan insert tidak akan dikeluarkan, atau status yang ada di dalam sesi tidak akan diperbarui*/ transaksi. } catch (Exception e) {E.PrintStackTrace (); transaction.rollback (); } akhirnya {hibernateutils.closesession (sesi); }} Melalui debugging:
1. Karena strategi generasi kunci utama adalah asli, setelah memanggil metode Simpan, pernyataan insert akan dikeluarkan segera, mengembalikan ID yang dihasilkan oleh database, memasukkan objek ke dalam manajemen sesi, memodifikasi properti yang ada di database, dan objek dalam pengumpulan sementara akan dibersihkan. Namun, karena tingkat isolasi MySQL, kami tidak dapat melihat data sebelum melakukan itu.
2. Setelah menelepon Save, objek dipanggil dan objek dikeluarkan dari sesi, yaitu, dikeluarkan dari entitas entitas di PersistenceContext.
3. Setelah memanggil metode Ext (), metode komit () dapat dipanggil dengan sukses. Komit dapat disimpan dengan sukses, karena sebelum memanggil komit (), metode flush () akan disebut secara implisit, yaitu, bersihkan cache dan cari objek dalam koleksi sementara untuk dimasukkan ke dalam database. Namun, Anda akan menemukan bahwa tidak ada data dalam pengumpulan sementara, sehingga pernyataan insert tidak akan dikeluarkan, dan properti keberadaan yang ada di persistenceContext tidak akan diperbarui.
Melalui kasus di atas, kita dapat melihat bahwa kadang -kadang kita perlu memanggil metode flush () untuk membersihkan cache. Selain itu, kami juga menemukan masalah dari yang di atas, yaitu ketika kami menyimpan () data, kami tidak dapat melihat data sebelum mengirimkannya, yaitu, tingkat isolasi database terbatas. Sekarang mari kita bicara tentang tingkat isolasi MySQL:
1. Periksa tingkat isolasi saat ini dari database MySQL:
pilih @@ tx_isolation;
Catatan: Dari gambar tersebut, kita dapat melihat bahwa tingkat isolasi default dari database MySQL dapat diulang, yang berarti bahwa tidak akan ada bacaan yang tidak dapat diulang, yaitu, harus diserahkan sebelum dapat dibaca.
2. Modifikasi tingkat isolasi mySQL saat ini (dengan asumsi itu tidak diserahkan untuk membaca, yaitu, dapat dibaca tanpa komit):
set transaction isolation level read uncommited;
Di atas adalah semua penjelasan terperinci dari Sesi Hibernate, Sesi Hibernate dan kode tingkat isolasi. Saya harap ini akan membantu semua orang. Teman yang tertarik dapat terus merujuk ke topik terkait lainnya di situs ini. Jika ada kekurangan, silakan tinggalkan pesan untuk menunjukkannya. Terima kasih teman atas dukungan Anda untuk situs ini!