1. Prinsip -prinsip dasar transaksi
Inti dari transaksi pegas sebenarnya adalah dukungan database untuk transaksi. Tanpa dukungan transaksi database, Spring tidak dapat menyediakan fungsi transaksi. Untuk database operasi JDBC murni, jika Anda ingin menggunakan transaksi, Anda dapat mengikuti langkah -langkah berikut:
1. Dapatkan koneksi koneksi con = driverManager.getConnection ()
2. Buka transaksi con.setautocommit (true/false);
3. Jalankan CRUD
4. Komit Transaksi / Transaksi Rollback Con.Commit () / Con.rollback ();
5. Tutup koneksi conn.close ();
Setelah menggunakan fungsi manajemen transaksi Spring, kami tidak dapat lagi menulis kode di Langkah 2 dan 4, tetapi akan secara otomatis dilakukan oleh Spirng. Jadi bagaimana musim semi membuka dan menutup transaksi sebelum dan sesudah crud yang kita tulis? Dengan menyelesaikan masalah ini, kita dapat memahami prinsip implementasi manajemen transaksi Spring dari keseluruhan. Izinkan saya memperkenalkan metode anotasi secara singkat sebagai contoh
1. Nyalakan driver anotasi dalam file konfigurasi dan identifikasi dengan anotasi @transactional pada kelas dan metode yang relevan.
2. Saat musim semi dimulai, itu akan mengurai dan menghasilkan kacang terkait. Pada saat ini, ia akan memeriksa kelas dan metode dengan anotasi yang relevan, dan menghasilkan proksi untuk kelas dan metode ini, dan melakukan injeksi konfigurasi terkait berdasarkan parameter yang relevan dari @transaction, sehingga transaksi yang relevan diproses untuk kami di proxy (mulai transaksi normal dan transaksi rollback pengecualian).
3. Transaksi Komit dan rollback lapisan database nyata diimplementasikan melalui Binlog atau Redo Log.
2. Sifat propagasi transaksi pegas
Atribut propagasi yang disebut transaksi pegas mendefinisikan bagaimana pegas harus menangani perilaku beberapa transaksi ketika mereka ada pada saat yang sama. Properti ini didefinisikan dalam definisi transaksi. Konstanta spesifik dijelaskan dalam tabel berikut:
AKU AKU AKU. Level Isolasi Basis Data
Dirty Reading: Satu transaksi menambahkan, menghapus dan memodifikasi data, tetapi tidak berkomitmen, dan transaksi lain dapat membaca data yang tidak berkomitmen. Jika transaksi pertama bergulir kembali saat ini, transaksi kedua membaca data kotor.
Tidak ada bacaan berulang: Dua operasi baca terjadi dalam satu transaksi. Antara operasi baca pertama dan operasi kedua, transaksi lainnya memodifikasi data. Pada saat ini, data yang dibaca dua kali tidak konsisten.
Bacaan Fantasi: Transaksi pertama memodifikasi data dalam kisaran tertentu dalam batch, dan transaksi kedua menambahkan satu data ke rentang ini. Pada saat ini, transaksi pertama akan kehilangan modifikasi dari data yang baru ditambahkan.
Ringkas :
Semakin tinggi tingkat isolasi, semakin banyak hal itu dapat memastikan integritas dan konsistensi data, tetapi semakin besar dampak pada kinerja konkurensi.
Tingkat isolasi default sebagian besar database dibaca ditugaskan, seperti SQLServer dan Oracle
Level isolasi default dari beberapa database adalah: baca yang dapat diulangi misalnya: mysql innodb
Iv. Tingkat Isolasi di Musim Semi
V. bersarang dari transaksi
Melalui pengetahuan teoretis di atas, kami secara kasar memahami beberapa atribut dan karakteristik transaksi database dan transaksi pegas. Selanjutnya, kami menganalisis beberapa skenario transaksi bersarang untuk memahami secara mendalam mekanisme perambatan transaksi musim semi.
Misalkan metode a () dari layanan transaksi luar A memanggil metode b () dari layanan dalam b
Propagation_required (default musim semi)
Jika tingkat transaksi serviceB.methodb () didefinisikan sebagai propagation_required, maka ketika serviceA.methoda () dieksekusi, transaksi telah dimulai pada musim semi. Pada saat ini, serviceB.methodb () dipanggil. ServiceB.methodb () melihat bahwa ia berjalan di dalam transaksi serviceA.methoda (), dan tidak ada transaksi baru yang dimulai.
Jika serviceB.methodb () berjalan, itu akan menetapkan transaksi untuk dirinya sendiri.
Dengan cara ini, jika suatu pengecualian terjadi di ServiceA.Methoda () atau di mana saja di dalam serviceB.methodb (), transaksi akan digulung kembali.
Propagation_requires_new
Misalnya, kami merancang bahwa ServiceA.Methoda () memiliki tingkat transaksi propagasi_required, dan serviceB.methodb () memiliki tingkat transaksi propagasi_requires_new.
Kemudian ketika serviceB.methodb () dieksekusi, transaksi di mana servicea.methoda () berada akan ditangguhkan, dan serviceB.methodb () akan memulai transaksi baru dan akan terus dieksekusi setelah transaksi layananb.methodb () selesai.
Perbedaan antara transaksi dan propagation_required -nya adalah tingkat rollback transaksi. Karena serviceB.methodb () adalah transaksi baru, maka ada dua transaksi yang berbeda. Jika serviceB.methodb () telah dikirimkan, maka servicea.methoda () gagal untuk rollback, serviceB.methodb () tidak akan rollback. Jika serviceB.methodb () gagal mundur, jika pengecualian yang dilemparkan oleh servicea.methoda () ditangkap, transaksi servicea.methoda () masih dapat diserahkan (terutama tergantung pada apakah pengecualian yang dilemparkan oleh B adalah pengecualian bahwa A akan kembali).
Propagation_supports
Dengan asumsi bahwa tingkat transaksi layananb.methodb () adalah propagasi_supports, ketika dieksekusi ke serviceB.methodb (), jika ditemukan bahwa serviceA.methoda () telah membuka transaksi, ia akan bergabung dengan transaksi saat ini. Jika ditemukan bahwa ServiceA.methoda () belum memulai transaksi, itu tidak akan memulai transaksi itu sendiri. Pada saat ini, transaksionalitas metode internal sepenuhnya tergantung pada transaksi terluar.
Propagation_nested
Situasinya menjadi lebih rumit sekarang. Properti transaksi serviceB.methodb () dikonfigurasi sebagai propagation_nested. Bagaimana keduanya akan bekerja sama saat ini? ServiceB#MethodB Jika rollback, maka transaksi internal (mis. ServiceB#MethodB) akan kembali ke SavePoint sebelum dieksekusi, sementara transaksi eksternal (mis. Servicea#Methoda) dapat memiliki dua cara penanganan berikut:
A. Menangkap pengecualian dan menjalankan logika cabang pengecualian
void methoda () {coba {serviceB.methodb (); } catch (someexception) {// jalankan bisnis lain, seperti serviceC.methodc (); }} Metode ini juga merupakan hal yang paling berharga tentang transaksi bersarang. Ini memainkan peran eksekusi cabang. Jika serviceB.methodb gagal, maka servicec.methodc () dieksekusi, dan serviceB.methodb telah kembali ke saveint sebelum dijalankan, jadi tidak ada data kotor yang dihasilkan (setara dengan metode ini tidak pernah dieksekusi). Fitur ini dapat digunakan dalam beberapa layanan khusus, dan baik propagation_required maupun propagation_requires_new tidak dapat melakukan ini.
B. Kode rollback/komit transaksi eksternal tidak membuat modifikasi apa pun. Jika transaksi internal (serviceB#methodB) rollback, maka First ServiceB.MethodB kembali ke savePoint sebelum dieksekusi (dalam hal apa pun), dan transaksi eksternal (mis. Servicea#methoda) akan memutuskan apakah itu berkomitmen atau rollback berdasarkan konfigurasi spesifik.
Tiga atribut propagasi transaksi lainnya pada dasarnya tidak efektif, jadi tidak ada analisis yang dilakukan di sini.
6. Ringkasan
Untuk tempat -tempat di mana transaksi diperlukan dalam proyek, saya menyarankan agar pengembang harus menggunakan antarmuka TransactionCallback Spring untuk mengimplementasikan transaksi. Jangan menggunakan anotasi transaksi musim semi secara membabi buta. Jika Anda harus menggunakan anotasi, Anda harus memiliki pemahaman terperinci tentang mekanisme propagasi dan tingkat isolasi transaksi pegas, jika tidak efek yang tidak terduga dapat terjadi.