1. Contoh skenario penggunaan
Sebelum kita memahami bagaimana @transactional digunakan, pertama -tama kita harus tahu apa @transactional berguna. Izinkan saya memberi Anda jempol: misalnya, ada banyak anggota di suatu departemen, dan keduanya disimpan di tabel departemen dan tabel anggota masing -masing. Saat menghapus departemen tertentu, misalkan kita menghapus anggota yang sesuai secara default. Namun, ini dapat terjadi selama eksekusi. Kami pertama -tama menghapus departemen dan kemudian menghapus anggota. Namun, departemen telah berhasil menghapusnya, dan pengecualian terjadi ketika menghapus anggota. Pada saat ini, kami berharap bahwa jika penghapusan anggota gagal, departemen yang sebelumnya dihapus juga akan membatalkan penghapusan. Skenario ini dapat digulung kembali menggunakan @transactional hal -hal.
2. Pengecualian diperiksa dan pengecualian yang tidak dicentang
Alasan mengapa kami membiarkan semua orang mengetahui konsep pengecualian yang diperiksa dan pengecualian yang tidak dicentang adalah bahwa:
Spring menggunakan pemrosesan transaksi deklaratif. Secara default, jika pengecualian yang tidak dicentang terjadi dalam metode operasi database beranotasi, semua operasi basis data akan menjadi rollback; Jika pengecualian terjadi adalah pengecualian yang diperiksa, operasi basis data masih akan dikirimkan secara default.
Pengecualian diperiksa:
Tidak valid, tidak dapat diprediksi dalam program. Misalnya, input pengguna yang tidak valid, file tidak ada, kesalahan tautan jaringan atau database. Ini semua adalah alasan eksternal dan tidak dikendalikan oleh program.
Harus ditangani secara eksplisit dalam kode. Misalnya, cobalah pemrosesan blok-tangkapan, atau lempar pengecualian ke lapisan sebelumnya dari tumpukan panggilan dengan deskripsi lemparan.
Diwarisi dari java.lang.exception (kecuali java.lang.runtimeException).
Pengecualian yang tidak dicentang:
Menunjukkan kesalahan, logika program salah. Ini adalah subclass dari runtimeException, seperti IllegalargumentException, NullpointerException dan IllegalStateException.
Tidak perlu secara eksplisit menangkap pengecualian yang tidak dicentang dalam kode untuk diproses.
Diwarisi dari java.lang.runtimeException (dan java.lang.runtimeException mewarisi dari java.lang.exception).
Melihat diagram struktur abnormal di bawah ini, mungkin lebih berlapis:
3. Contoh penggunaan @transactional
Contoh ini menggunakan Eclipse+Maven. Maven hanya dikelola sebagai toples, dan bahkan teman -teman kera Maven yang tidak mengerti dapat memahaminya.
3.1. File Konfigurasi Musim Semi
TX namespace harus dikonfigurasi terlebih dahulu sebagai berikut:
Untuk menggunakan @manajemen transaksi berbasis transaksional, konfigurasi berikut diperlukan di musim semi:
<bean id = "appTransactionManager"> <name properti = "DataSource" ref = "DataSource" /> < /bean> <tx: anotasi-digerakkan proxy-target-class = "false" transaction-manager = "apptransactionManager" />
Seluruh file konfigurasi pegas blogger:
<? XML Versi = "1.0" encoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmls xmlns: context = "http://www.springframework.org/schema/context" xmlns: tx = "http://www.springframework.org/schema/tx" xmlns: aop = "http:/schema/tx" xmlns: aop = "http:/schema. XSI: schemalocation = "http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.4 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-weans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.spramework.org/schema/context http://www.springframework.org/schema/www.spramework.org/schema/contex File Konfigurasi JDBC-> <bean id = "properti configurer"> <property name = "locations"> <cist> <value> classpath: properti/*. Properties </ value> <!-Jika ada beberapa file konfigurasi, terus tambahkan di sini-> </cist> </prope> </tean> <!-Sumber data konfigurasi-> </cist> </preate "</bean> <!-Sumber data konfigurasi-> </list> </seve" </bean> <!-Configure Id-> <!-Mengkonfigurasi Properti-> <!-Mengkonfigurasi Properti-> <!-<properti nama = "driverclassname" value = "com.mysql.jdbc.driver" /> <name properti = "url" value = "jdbc: mysql: // localhost: 3306 /learning" /<name jdbc: mysql: // localhost: 3306 /learning " /<a name =" name = "User =" "" "" "" "" "" name "name =" ucwning = "" " value = "natal258@"/>-> <!-Gunakan properti untuk mengonfigurasi-> <name properti = "driverclassname"> <value> $ {jdbc_driverclassname} </ value> </prop Property> </property name = "value =" jdbc_url} </value> </property> nama properti = "jdbc_url} </value> </value> </value =" {jdbc_url} </value> </property> nama property = "jdbc_url} </value> </value> </value =" {jdbc_url} </value> </property> nama = "" jdbc_url} </value> </value> nama propert <value> $ {jdbc_username} </ value> </property> <property name = "password"> <value> $ {jdbc_password} </ value> </property> </tr Properte> </triver = "DataSource"/</tx: datasource "datasource" ref = "DataSource"/ proxy-target-class = "false" transaction-manager = "appTransactionManager" /> <!-Secara otomatis memindai semua file antarmuka mapper yang sesuai dengan xxxxmapper.xml, sehingga Anda tidak perlu mengkonfigurasi pemetaan mPper secara manual satu per satu. Selama kelas antarmuka mapper dan file pemetaan mapper saling berhubungan. -> <Bean> <nama properti = "Basepackage" value = "com.luo.dao" /> </ bean> <!-Mengkonfigurasi file mybatis, mapperlocations configure ** mapper.xml lokasi file, configlocation "DATACOCE =" DATACOCE = "DATACOCE =" DATACOCE = "DATACOCE" DATACOCE = "DATACOCE" DATACOCE = "DATACOCE" "DATACOCE" "DATACOCE" "SQLSESICE" "SQLOCORCE" "SQLSIORCE" "SQLSIORCE" "SQLSIORCE" " <nama properti = "mapperlocations" value = "classpath: mapper/*. xml"/> <name properti = "configlocation" value = "classpath: mybatis/mybatis-config.xml"/> <!-<name properti = "TypealiSespackage" value = "com.tianian.kkeditor.mody-foulated-typealiSespackage" value = "com.tianian.kkeditor.moded" —ypealiSespackage "value =" com.tianian.kkeditor.moded "—ypealiSespackage" value = "com.tianian.kkeditor.moded" —pealieD "value =" com.tianian.kkeditor.mod "—pealiSespackage" value = "com.tianian.kkeditor.modatated" Beans-> <Context: Component-Scan Base-Package = "com.luo.service" /> </tagel>3.2. Gunakan @transactional untuk menambahkan anotasi ke metode kelas implementasi pengguna
@Transactional (propagation = propagation.Required) public void addUser (pengguna pengguna) {userdao.adduser (pengguna); String string = null; if (string.equals ("")) {int i = 0; }}Dalam metode di atas, saya sengaja membuatnya memiliki pengecualian pointer nol dan segalanya akan berputar kembali
3.3. Jalankan kelas tes unit
@Test public void addusertest () {user user = new user (); user.setusername ("luoguohui1"); user.setUserPassword ("luoguohui1"); Userservice.adduser (pengguna);}Saya menemukan bahwa itu tidak dapat dimasukkan, tetapi jika @transactional dihapus, kodenya adalah sebagai berikut. Meskipun pengecualian terjadi, masih ada data yang sesuai yang ditambahkan ke database:
3.4. Unduh kode sumber
Unduh kode sumber terakhir artikel ini: first_maven_project_jb51.rar
4. Konsep yang @transactional di musim semi harus dipahami
@Transactional di musim semi didasarkan pada mekanisme proxy dinamis dan memberikan mekanisme manajemen transaksi transparan untuk memfasilitasi dan menyelesaikan masalah yang dihadapi dalam pengembangan.
Secara umum, ini adalah mengomentari metode atau antarmuka atau kelas melalui kode berikut:
@Transactional (propagation = propagation.not_supported)
Propagasi mendukung 7 mekanisme propagasi yang berbeda:
Diperlukan: Jika ada transaksi, transaksi saat ini didukung. Jika tidak ada transaksi, transaksi baru dimulai.
Dukungan: Jika ada transaksi, transaksi saat ini didukung. Jika tidak ada transaksi, pelaksanaan non-transaksi. Namun, untuk manajer transaksi sinkronisasi transaksi, propagation_supports sedikit berbeda dari tidak menggunakan transaksi.
NOT_SUPPORTED: Selalu jalankan non-transaksional dan tangguhkan transaksi yang ada.
MembutuhkanNew: Selalu memulai transaksi baru. Jika transaksi sudah ada, transaksi yang ada ditangguhkan.
Wajib: Jika transaksi sudah ada, mendukung transaksi saat ini. Jika tidak ada transaksi aktif, pengecualian dilemparkan.
Never: Selalu jalankan non-transaksional, jika ada transaksi aktif, pengecualian dilemparkan
Nested: Jika ada transaksi aktif, ia berjalan dalam transaksi bersarang. Jika tidak ada transaksi aktif, tekan properti yang diperlukan untuk dieksekusi.
Berikut adalah beberapa hal yang perlu diperhatikan, yang harus dibaca, jika tidak, jika Anda menemukan berbagai jebakan, blogger tidak mengingatkan Anda:
Berikut adalah beberapa hal yang perlu diperhatikan, yang harus dibaca, jika tidak, jika Anda menemukan berbagai jebakan, blogger tidak mengingatkan Anda:
Berikut adalah beberapa hal yang perlu diperhatikan, yang harus dibaca, jika tidak, jika Anda menemukan berbagai jebakan, blogger tidak mengingatkan Anda:
Tambahkan anotasi @transactional di mana manajemen transaksi diperlukan. Anotasi @transactional dapat diterapkan pada definisi antarmuka dan metode antarmuka, definisi kelas dan metode kelas publik.
Anotasi @transactional hanya dapat diterapkan pada metode dengan visibilitas publik. Jika Anda menggunakan anotasi @transactional pada metode yang dilindungi, pribadi, atau paket yang terlihat, itu tidak akan melaporkan kesalahan, tetapi metode beranotasi ini tidak akan menampilkan pengaturan transaksi yang dikonfigurasi.
Perhatikan bahwa terjadinya anotasi @transactional tidak cukup untuk memungkinkan perilaku transaksi, itu hanya semacam metadata. Elemen konfigurasi harus digunakan dalam file konfigurasi untuk benar -benar mengaktifkan perilaku transaksi.
Mengontrol apakah proxy berbasis antarmuka atau berbasis kelas dibuat melalui nilai atribut "proxy-target-class" elemen. Jika nilai genre "proxy-target-class" diatur ke "true", maka proxy berbasis kelas akan berfungsi (ini diperlukan untuk cglib.jar di classpath). Jika nilai genre "proxy-target-class" diatur ke "false" atau properti ini dihilangkan, maka proxy berbasis antarmuka JDK standar akan berfungsi.
Tim Spring merekomendasikan penggunaan anotasi @transactional pada kelas tertentu (atau metode kelas) daripada pada antarmuka apa pun yang ingin diimplementasikan oleh kelas. Menggunakan anotasi @transactional pada antarmuka hanya akan berlaku ketika Anda mengatur proxy berbasis antarmuka. Karena anotasi tidak dapat diwarisi, ini berarti bahwa jika proxy berbasis kelas digunakan, pengaturan transaksi tidak akan dikenali oleh proxy berbasis kelas, dan objek tidak akan dibungkus oleh proxy transaksi.
@Transactional's Transaction diaktifkan, baik proxy berbasis antarmuka atau proxy berbasis kelas. Jadi di kelas yang sama, satu metode memanggil metode lain dengan transaksi, transaksi tidak akan berhasil.
Di atas adalah semua konten artikel ini. Saya berharap ini akan membantu untuk pembelajaran semua orang dan saya harap semua orang akan lebih mendukung wulin.com.