1. Gambaran keseluruhan
Tutorial ini akan membincangkan cara yang betul untuk mengkonfigurasi Transaksi Musim Semi , cara menggunakan anotasi @Transactional dan perangkap biasa.
Untuk perbincangan yang lebih mendalam mengenai konfigurasi ketekunan teras, lihat tutorial Spring with JPA.
Pada asasnya, terdapat dua cara berbeza untuk mengkonfigurasi Transaksi - anotasi dan AOP - masing-masing mempunyai kelebihan masing-masing. Kami akan membincangkan konfigurasi anotasi yang lebih biasa di sini.
2. Konfigurasikan Transaksi
Spring 3.1 TETAPI memperkenalkan yang @EnableTransactionManagement anotasi yang boleh kita gunakan dalam @Configuration kelas dan membolehkan sokongan transaksi:
@Configuration @EnableTransactionManagement public class PersistenceJPAConfig{ @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(){ //... } @Bean public PlatformTransactionManager transactionManager(){ JpaTransactionManager transactionManager = new JpaTransactionManager(); transactionManager.setEntityManagerFactory( entityManagerFactoryBean().getObject() ); return transactionManager; } }
Namun, jika kita menggunakan projek Spring Boot, dan mempunyai dependensi spring-data- * atau spring-tx pada classpath, maka pengurusan transaksi akan diaktifkan secara lalai .
3. Konfigurasikan Transaksi Dengan XML
Sebelum 3.1 atau jika Java bukan pilihan, berikut adalah konfigurasi XML, menggunakan sokongan anotasi dan ruang nama:
4. Anotasi @Transactional
Dengan urus niaga yang dikonfigurasi, kita kini dapat memberi anotasi kacang dengan @Transactional sama ada di peringkat kelas atau kaedah:
@Service @Transactional public class FooService { //... }
Anotasi menyokong konfigurasi lebih lanjut juga:
- yang Penyebaran Jenis urus niaga
- yang Level Pengasingan transaksi
- yang Timeout untuk operasi yang dibalut dengan transaksi
- yang baca sahaja bendera - tanda-tanda untuk pembekal kegigihan bahawa transaksi perlu dibaca sahaja
- yang Rollback peraturan untuk urus niaga tersebut
Perhatikan bahawa - secara lalai, pemulangan berlaku untuk masa berjalan, pengecualian yang tidak dicentang sahaja. Pengecualian yang diperiksa tidak mencetuskan kemunduran transaksi. Kita tentu saja dapat mengkonfigurasi tingkah laku ini dengan parameter anotasi rollbackFor dan noRollbackFor .
5. Perangkap Berpotensi
5.1. Transaksi dan Proksi
Pada tahap yang tinggi, Spring membuat proksi untuk semua kelas yang diberi anotasi dengan @Transactional - sama ada di kelas atau kaedah apa pun. Proksi membolehkan rangka kerja menyuntik logik transaksi sebelum dan selepas kaedah berjalan - terutamanya untuk memulakan dan melakukan transaksi.
Yang penting untuk diingat adalah bahawa, jika kacang transaksional melaksanakan antara muka, secara lalai proksi akan menjadi Java Dynamic Proxy. Ini bermaksud bahawa hanya panggilan kaedah luaran yang masuk melalui proksi yang akan dipintas. Sebarang panggilan pemanggil sendiri tidak akan memulakan transaksi apa pun , walaupun kaedah tersebut mempunyai anotasi @Transactional .
Perhatian lain untuk menggunakan proksi adalah bahawa hanya kaedah awam yang harus diberi penjelasan dengan @Transactional. Kaedah penglihatan lain akan mengabaikan anotasi secara senyap kerana ini tidak diproksi.
Artikel ini membincangkan perangkap proxy yang lebih terperinci di sini.
5.2. Mengubah Tahap Pengasingan
Kami juga dapat mengubah tahap pengasingan transaksi:
@Transactional(isolation = Isolation.SERIALIZABLE)
Perhatikan bahawa ini sebenarnya telah diperkenalkan pada musim bunga 4.1; jika kita menjalankan contoh di atas sebelum musim bunga 4.1, ia akan menghasilkan:
org.springframework.transaction.InvalidIsolationLevelException : JPA standard tidak menyokong tahap pengasingan tersuai - gunakan JpaDialect khas untuk pelaksanaan JPA anda
5.3. Transaksi Hanya Baca
The readOnly flag usually generates confusion, especially when working with JPA; from the Javadoc:
This just serves as a hint for the actual transaction subsystem; it will not necessarily cause failure of write access attempts. A transaction manager which cannot interpret the read-only hint will not throw an exception when asked for a read-only transaction.
The fact is that we can't be sure that an insert or update will not occur when the readOnly flag is set. This behavior is vendor dependent, whereas JPA is vendor agnostic.
It's also important to understand that the readOnly flag is only relevant inside a transaction. If an operation occurs outside of a transactional context, the flag is simply ignored. A simple example of that would call a method annotated with:
@Transactional( propagation = Propagation.SUPPORTS,readOnly = true )
from a non-transactional context – a transaction will not be created and the readOnly flag will be ignored.
5.4. Transaction Logging
A helpful method to understand transactional related issues is fine-tuning logging in the transactional packages. The relevant package in Spring is “org.springframework.transaction”, which should be configured with a logging level of TRACE.
6. Conclusion
Kami merangkumi konfigurasi asas semantik transaksional menggunakan Java dan XML, bagaimana menggunakan @Transactional dan amalan terbaik Strategi Transaksional.
Seperti biasa, kod yang disajikan dalam artikel ini terdapat di Github.