javax.transaction.Transactional vs org.springframework.transaction.annotation.Transactional

153

Saya tidak mengerti apa perbedaan aktual antara anotasi javax.transaction.Transactionaldan org.springframework.transaction.annotation.Transactional?

Apakah org.springframework.transaction.annotation.Transactionalperpanjangan javax.transaction.Transactionalatau mereka memiliki arti yang sama sekali berbeda? Kapan masing-masing digunakan? Spring @Transactinaldi lapisan layanan dan javax di DAO?

Terimakasih telah menjawab.

stamis
sumber

Jawaban:

125

Spring telah mendefinisikan anotasi Transaksionalnya sendiri untuk membuat metode kacang Spring transaksional, tahun lalu.

Java EE 7 akhirnya melakukan hal yang sama dan sekarang memungkinkan metode kacang CDI menjadi transaksional, selain metode EJB. Jadi sejak Java EE 7, ia juga mendefinisikan anotasi Transaksional sendiri (jelas tidak dapat menggunakan kembali yang Spring).

Dalam aplikasi Java EE 7, Anda akan menggunakan anotasi Java EE.

Dalam aplikasi Musim Semi, Anda akan menggunakan anotasi Musim Semi.

Penggunaannya sama: menginformasikan wadah (Java EE atau Spring) bahwa suatu metode bersifat transaksional.

JB Nizet
sumber
28
Lebih dari itu: untuk menguasai alam semesta, Spring juga menambahkan dukungan implisit javax.transaction.Transactionalsehingga seseorang sekarang dapat menggunakannya juga dalam aplikasi Spring tanpa tindakan tambahan. IMO, ini keputusan yang sangat buruk dari sudut pandang desain , karena dari pengalaman saya banyak pengembang yang secara tidak sadar membingungkan kedua kode ini yang menyebabkan masalah setelahnya.
Yuriy Nakonechnyy
16
Selain itu, org.springframework.transaction.annotation.Transactionalmenawarkan lebih banyak pilihan (seperti readOnly, timeout) daripadajavax.transaction.Transactional
pierrefevrier
1
@Yura, masalah apa yang telah Anda amati?
Lee Chee Kiam
1
@LeeCheeKiam silakan lihat dua jawaban di bawah ini
Yuriy Nakonechnyy
50

Perbedaan lainnya adalah bagaimana Spring menangani anotasi @Transaksional

  • org.springframework.transaction.annotation.Transaksi selalu diperhitungkan
  • javax.transaction.Transactional diperhitungkan hanya ketika transaksi EJB3 hadir. Kehadiran transaksi EJB3 dilakukan dengan memeriksa apakah kelas javax.ejb.TransactionAttributetersedia di classpath (dari versi 2.5.3 ke 3.2.5). Dengan demikian Anda dapat berakhir dengan anotasi yang tidak diperhitungkan jika hanya javax.transaction.Transactionalada di kelas Anda dan tidak javax.ejb.TransactionAttribute. Ini dapat terjadi jika Anda bekerja dengan Hibernate: hibernate-core (4.3.7.Final) tergantung pada jboss-transaction-api_1.2_spec (1.0.0.Final), yang tidak menyediakan javax.ejb.TransactionAttribute.
Jidehem
sumber
9
Saya pikir ini bukan masalah lagi dengan Spring 4.2.0: javax.transaction. Anotasi transaksional juga didukung sebagai pengganti drop-in untuk anotasi Spring sendiri
Arend v. Reinersdorff
itu tidak selalu diambil, jika itu pada metode pribadi misalnya tidak akan diambil.
strash
36

Harap berhati-hati, (masalah ini terjadi pada kucing jantan),

Jika aplikasi Anda adalah aplikasi web SPRING dan Anda menggunakan mekanisme penanganan transaksi Spring @org.springframework.transaction.annotation.Transactional , maka jangan campur dengan javax.transaction.Transactional.

Itu selalu digunakan, @org.springframework.transaction.annotation.Transactional dalam aplikasi pegas secara konsisten.

Kalau tidak, kita mungkin berakhir dengan kesalahan ini,

org.springframework.orm.jpa.JpaSystemException: commit failed; nested exception is org.hibernate.TransactionException: commit failed

........

Caused by: java.sql.SQLException: Protocol violation: [0]
Lyju I Edwinson
sumber
1
Catatan: jawaban ini adalah kasus khusus dari jawaban saya
Jidehem
3

Lingkup transaksi deklaratif

Baik @Transactionanotasi Spring dan JPA memungkinkan Anda untuk menentukan cakupan transaksi aplikasi yang diberikan.

Jadi, jika metode layanan dijelaskan dengan @Transactionalpenjelasan, itu akan berjalan dalam konteks transaksional. Jika metode layanan menggunakan beberapa DAO atau Repositori, semua operasi penulisan iklan baca akan dieksekusi dalam transaksi basis data yang sama.

Musim semi @Transactional

The org.springframework.transaction.annotation.Transactionalpenjelasan telah tersedia sejak 1,2 versi kerangka Spring (sekitar tahun 2005), dan memungkinkan Anda untuk mengatur properti transaksional berikut:

  • isolation: tingkat isolasi basis data yang mendasarinya
  • noRollbackFordan noRollbackForClassName: daftar Exceptionkelas Java yang dapat dipicu tanpa memicu rollback transaksi
  • rollbackFordan rollbackForClassName: daftar Exceptionkelas Java yang memicu pengembalian transaksi saat dilempar
  • propagation: jenis propagasi transaksi yang diberikan oleh PropagationEnum. Misalnya, jika konteks transaksi dapat diwariskan (misalnya, REQUIRED) atau konteks transaksi baru harus dibuat (misalnya, REQUIRES_NEW) atau jika pengecualian harus dilemparkan jika tidak ada konteks transaksi yang ada (misalnya, MANDATORY) atau jika pengecualian harus dilemparkan jika konteks transaksi saat ini ditemukan (misalnya, NOT_SUPPORTED).
  • readOnly: apakah transaksi saat ini hanya membaca data tanpa menerapkan perubahan apa pun.
  • timeout: berapa detik seharusnya konteks transaksi dibiarkan berjalan sampai pengecualian timeout dilemparkan.
  • valueatau transactionManager: nama TransactionManagerkacang Spring yang akan digunakan saat mengikat konteks transaksi.

Java EE @Transactional

The javax.transaction.Transactionalpenjelasan ditambahkan oleh Java EE 7 spesifikasi (sekitar tahun 2013). Jadi, anotasi Java EE ditambahkan 8 tahun kemudian dari padanan Springnya.

Java EE @Transactionalhanya mendefinisikan 3 atribut:

  • dontRollbackOn: daftar Exceptionkelas Java yang dapat dipicu tanpa memicu rollback transaksi
  • rollbackOn: daftar Exceptionkelas Java yang memicu pengembalian transaksi saat dilemparkan
  • value: strategi propagasi, yang diberikan oleh TxTypeEnum. Misalnya, jika konteks transaksi dapat diwariskan (misalnya, REQUIRED) atau konteks transaksi baru harus dibuat (misalnya, REQUIRES_NEW) atau jika pengecualian harus dilemparkan jika tidak ada konteks transaksi yang ada (misalnya, MANDATORY) atau jika pengecualian harus dilemparkan jika konteks transaksi saat ini ditemukan (misalnya, NOT_SUPPORTED).

Yang mana yang harus dipilih?

Jika Anda menggunakan Spring atau Spring Boot, gunakan @Transactionalanotasi Spring , karena memungkinkan Anda untuk mengonfigurasi lebih banyak atribut daripada @Transactionalanotasi Java EE .

Jika Anda menggunakan Java EE saja, dan Anda menggunakan aplikasi Anda pada server aplikasi Java EE, maka gunakan penjelasan Java EE `` @ Transactional`.

Untuk perincian lebih lanjut tentang perbedaan konfigurasi tingkat isolasi saat menggunakan @Transactionaldefinisi Spring atau Java EE , lihat artikel ini .

Vlad Mihalcea
sumber