1. Saat mybatis digunakan sendiri, gunakan SQLSession untuk menangani transaksi:
kelas publik mybatistxtest {private static SQLSessionFactory SQLSessionFactory; Pembaca Pembaca Statis Pribadi; @Beforeclass public static void setupbeforeclass () melempar Exception {try {reader = Resources.GetResourCeArreader ("configuration.xml"); SQLSessionFactory = SQLSessionFactoryBuilder baru (). Build (pembaca); } akhirnya {if (reader! = null) {reader.close (); }}} @Test public void updateUsertXtest () {SQLSession sesi = sqlSessionFactory.opensession (false); // buka sesi dan transaksi mulai coba {iusermapper mapper = session.getMapper (iusermapper.class); Pengguna pengguna = pengguna baru (9, "transaksi uji"); int terpengaruh = mapper.updateUser (pengguna); // Pernyataan komit tidak dieksekusi karena pengguna pengecualian berikutnya = pengguna baru (10, "Tes Transaksi terus menerus"); int terpengaruhCount2 = mapper.updateUser (user2); // Pernyataan komit int i = 2/0 tidak dieksekusi karena pengecualian berikutnya; // Pengecualian runtime dipicu session.commit (); // Kirim sesi, yaitu, transaksi komit} akhirnya {session.close (); // tutup sesi dan rilis sumber daya}}}
2. Setelah berintegrasi dengan Spring, gunakan manajemen transaksi Spring:
Salah satu alasan utama untuk menggunakan Spring Mybatis adalah bahwa hal itu memungkinkan Mybatis untuk berpartisipasi dalam manajemen transaksi Spring. Daripada membuat manajer transaksi spesifik baru untuk MyBatis, mybatis-Spring menggunakan DataSourCetransactionManager yang ada di musim semi.
Setelah DataSourCeTransActionManager dikonfigurasi, Anda dapat mengonfigurasi transaksi di musim semi seperti biasanya. Anotasi @transactional dan konfigurasi gaya AOP didukung. Selama pemrosesan transaksi, objek SQLSession terpisah akan dibuat dan digunakan. Ketika transaksi selesai, sesi ini akan dilakukan atau digulung kembali dengan cara yang sesuai.
Setelah transaksi dibuat, Spring MyBatis akan mengelola transaksi secara transparan. Tidak perlu kode tambahan di DAO atau kelas layanan Anda.
1. Konfigurasi Standar
Untuk mengaktifkan pemrosesan transaksi Spring, cukup buat objek DataSourCetransActionManager di file konfigurasi XML Spring:
<bean id = "TransactionManager"> <name properti = "DataSource" ref = "DataSource"/> </ bean>
DataSource yang ditentukan umumnya dapat berupa sumber data JDBC yang Anda gunakan Spring. Ini termasuk kumpulan koneksi dan sumber data yang diperoleh melalui pencarian JNDI.
Perhatikan bahwa sumber data yang ditentukan untuk manajer transaksi harus merupakan sumber data yang sama dengan yang digunakan untuk membuat SQLSessionFactoryBean, jika tidak, manajer transaksi tidak akan berfungsi.
2. Transaksi Manajemen Kontainer
Jika Anda menggunakan Container JEE dan ingin Spring berpartisipasi dalam transaksi manajemen kontainer, Spring harus dikonfigurasi menggunakan JTATRansActionManager atau subkelas yang ditentukan wadahnya. Cara paling nyaman untuk melakukan ini adalah dengan menggunakan namespace transaksi Spring:
<TX: JTA-Transaction-Manager/>
Dalam konfigurasi ini, mybatis akan sama dengan sumber daya transaksi pegas lainnya yang dikonfigurasi oleh transaksi manajemen kontainer. Spring akan secara otomatis menggunakan transaksi kontainer yang ada, melampirkan SQLSESSION untuk itu. Jika transaksi tidak dimulai, atau jika transaksi diperlukan, pegas akan memungkinkan wadah baru untuk mengelola transaksi.
Perhatikan bahwa jika Anda ingin mengelola transaksi menggunakan wadah dan bukan manajemen transaksi Spring, Anda harus mengonfigurasi SQLSessionFactoryBean untuk menggunakan MyBatis Basic Mybatis ManagedTransactionFactory alih -alih Manajer Transaksi Musim Semi lainnya:
<bean id = "sqlSessionFactory"> <properti name = "DataSource" ref = "DataSource"/> <name properti = "TransactionFactoryClass"> <value> org.apache.atis.transaction.managed.ManagedTransActionFactory "/> </properti> </bean>
3. Manajemen Transaksi Pemrograman
SQLSession MyBatis menyediakan metode tertentu untuk menangani transaksi terprogram. Tetapi ketika menggunakan Spring Mybatis, kacang akan disuntikkan menggunakan SQLSession atau Mapper yang dikelola Spring. Itu berarti musim semi biasanya menangani transaksi. Anda tidak dapat menghubungi SQLSession.Commit (), SQLSession.rollback (), atau SQLSession.Close () metode pada SQLSession yang dikelola Spring. Jika Anda melakukan ini, ExportedOperationException yang tidak didukung akan dilemparkan. Perhatikan bahwa metode tersebut tidak dapat diakses saat menggunakan pemetaan yang disuntikkan. Terlepas dari apakah koneksi diatur ke AutoCommit atau tidak, pelaksanaan metode data SQLSession atau panggilan apa pun ke metode mapper di luar transaksi pegas akan secara otomatis dilakukan. Berikut adalah contoh transaksi pemrograman:
DefaultTransactionDefinition def = new DefaultTransactionDefinition (); def.setPropagationBehavior (transactionDefinition.propagation_required); Status transactionStatus = txManager.getTransaction (def); coba {usermapper.insertuser (pengguna); } catch (myException ex) {throw ex; } txManager.Commit (status);4.@Metode Transaksional:
Buat file beans-da-tx.xml di bawah classpath dan tambahkan konfigurasi transaksi berdasarkan kacang-da.xml (seri V):
<!-Transaction Manager-> <bean id = "txManager"> <name properti = "DataSource" ref = "DataSource" /> < /bean> <!-Driver anotasi transaksi, kelas dan metode yang ditandai @transactional akan menjadi transaksional-> <tx: <tere-driven transaction-manager = "TXManager =" TXManager = "<tx =" User-Bean " /User-Driven Transaction-Manager =" TXManager = "TXMANAGER" / /<tx = "User-BE" ID "TXMANAGER =" TXMANAGER ""
Kategori Layanan:
@Service ("Userservice") kelas publik Userservice {@Autowired iusermapper mapper; Public int BatchUpDateUsers WHENException () {// pengguna non-transaksional pengguna = pengguna baru (9, "sebelum pengecualian"); int terpengaruh = mapper.updateUser (pengguna); // Eksekusi Pengguna Sukses Pengguna2 = Pengguna Baru (10, "Setelah Pengecualian"); int i = 1 /0; // lempar pengecualian runtime int terpengaruhcount2 = mapper.updateuser (user2); // tidak dieksekusi if (terpengaruhcount == 1 && terpengaruhCount2 == 1) {return 1; } return 0; } @Transactional Public Int TXUpDateUsersswhenException () {// pengguna transaksional Pengguna = pengguna baru (9, "sebelum pengecualian"); int terpengaruh = mapper.updateUser (pengguna); // rollback karena pengguna pengecualian selanjutnya User2 = pengguna baru (10, "setelah pengecualian"); int i = 1 /0; // Lemparkan pengecualian runtime dan transaksi rollback int terpengaruhCount2 = mappper.updateuser (user2); // tidak dieksekusi if (terpengaruhcount == 1 && terpengaruhCount2 == 1) {return 1; } return 0; }}Di kelas tes:
@Runwith (springjunit4classrunner.class) @contextConfiguration (lokasi = {"classpath: beans-da-tx.xml"}) kelas publik springintegratetxtest {@Resource UserserService UserService; @Test public void updateUsersExceptionTest () {UserserVice.BatchUpDateUsersWhenException (); } @Test public void tXupDateUsersExceptontest () {UserserVice.txUpdateUsersWhenException (); }}
5. Metode TransactionTemplate
Tambahkan kacang-da-tx.xml:
<bean id = "txtemplate"> <konstruktor-arg type = "org.springframework.transaction.platformransactionManager" ref = "transactionManager" /> </ bean>
Bergabunglah di kelas Userservice:
@Autowired (wajib = false) transactionTemplate txtemplate; Public int txUpdateUsers whenExceptionViatXtemplate () {int retval = txtemplate.execute (TransactionCallback baru <Integer> () {@Override Public integer dointransaction (status transactionStatus) {// Pengguna Operasi Transaksi = Pengguna baru (9, "sebelum pengecualian") {// Pengguna Operasi Transaksi = Pengguna baru (9, "sebelum pengecualian"); karena pengguna pengecualian berikutnya2 = pengguna baru (10, setelah pengecualian "); return returnval; }Tambahkan ke kelas SpringIntegratEtXtest:
@Test public void updateAsers whenExceptionViatxtemplateTest () {UserserVice.txUpdateUsersswhenExceptionViatXtemplate (); //}CATATAN: Tidak dapat menangkap Exception atau RunimeException tanpa melempar:
@Transactional public int txUpdateUsers WhyExceptionAndCatch () {// Operasi transaksional, tetapi kerangka kerja periferal tidak dapat menangkap pengecualian dan mengirimkannya jika eksekusi benar. coba {pengguna pengguna = pengguna baru (9, "sebelum pengecualian"); int terpengaruh = mapper.updateUser (pengguna); // Eksekusi berhasil pengguna pengguna2 = pengguna baru (10, "setelah pengecualian"); int i = 1 /0; // lempar pengecualian runtime int terpengaruhcount2 = mapper.updateuser (user2); // tidak dieksekusi if (terpengaruhcount == 1 && terpengaruhCount2 == 1) {return 1; }} catch (Exception e) {// Semua pengecualian ditangkap tanpa melempar e.printstacktrace (); } return 0; }