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


152

Я не розумію, яка насправді різниця між анотаціями javax.transaction.Transactionalта org.springframework.transaction.annotation.Transactional?

Це org.springframework.transaction.annotation.Transactionalрозширення javax.transaction.Transactionalабо вони мають зовсім інше значення? Коли кожен із них слід використовувати? Весна @Transactinalв шарі обслуговування та javax в DAO?

Дякую за відповідь.

Відповіді:


125

Весна визначила свою власну транзакційну анотацію, щоб зробити весняні методи бобів транзакційними років тому.

Нарешті, Java EE 7 зробила те ж саме, і тепер дозволяє методам CDI bean бути транзакційними, крім методів EJB. Отже, оскільки Java EE 7, вона також визначає власну анотацію щодо транзакцій (вона, очевидно, не може використати весняну).

У додатку Java EE 7 ви будете використовувати примітку Java EE.

У програмі Spring ви використовуєте анотацію Spring.

Їх використання те саме: інформування контейнера (Java EE або Spring), що метод є транзакційним.


28
Більше того: для того, щоб управляти Всесвітом, Spring також додала неявну підтримку для того, javax.transaction.Transactionalщоб тепер можна було використовувати її також у додатках Spring без додаткових дій. ІМО, це було досить поганим рішенням з точки зору дизайну , тому що, з мого досвіду, багато розробників не свідомо плутають цих двох у своєму коді, що призводить до проблем згодом.
Юрій Наконечний

16
Крім того, org.springframework.transaction.annotation.Transactionalпропонується більше варіантів (як readOnly, наприклад timeout)javax.transaction.Transactional
pierrefevrier

1
@yura, які проблеми ти спостерігав?
Лі Чі Кіам

1
@LeeCheeKiam дивіться дві відповіді нижче
Юрій Наконечний

50

Ще одна відмінність полягає в тому, як Spring обробляє анотації @Transactional

  • org.springframework.transaction.annotation.Transactional завжди враховується
  • javax.transaction.Transactional враховується лише за наявності транзакцій EJB3. Присутність транзакцій EJB3 здійснюється шляхом перевірки наявності класу javax.ejb.TransactionAttributeна шляху класу (від версії 2.5.3 до 3.2.5). Таким чином, ви можете закінчитись тим, що ваші анотації не враховуються, якщо вони лише javax.transaction.Transactionalє у вашому класі, а ні javax.ejb.TransactionAttribute. Це може бути, якщо ви працюєте з Hibernate: hibernate-core (4.3.7.Final) залежить від jboss-транзакції-api_1.2_spec (1.0.0.Final), яка не забезпечує javax.ejb.TransactionAttribute.


його не завжди приймають, якщо його, наприклад, за приватним методом, він не буде взято.
страш

36

Будьте обережні, (ця проблема трапилась у tomcat),

Якщо у вашій програмі є веб-додаток SPRING і ви використовуєте механізм обробки транзакцій Spring @org.springframework.transaction.annotation.Transactional, тобто не змішуйте його з javax.transaction.Transactional.

Тобто завжди використовуйте @org.springframework.transaction.annotation.Transactionalу весняному застосуванні послідовно.

Інакше ми можемо виявити цю помилку,

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

........

Caused by: java.sql.SQLException: Protocol violation: [0]

1
Зауважте: ця відповідь є особливим випадком моєї відповіді
Джидехем

3

Декларативний обсяг угоди

Як @Transactionанотація Spring, так і JPA дозволяють визначити обсяг транзакції з додатком.

Отже, якщо метод обслуговування зазначається з @Transactionalанотацією, він запускається в транзакційному контексті. Якщо в сервісному методі використовується кілька DAO або сховищ, всі операції з читання оголошень будуть виконуватися в одній транзакції з базою даних.

Весна @Transactional

org.springframework.transaction.annotation.TransactionalАнотацій доступний з версії рамок Spring 1.2 (ок 2005), і це дозволяє встановити наступні транзакційні властивості:

  • isolation: базовий рівень ізоляції бази даних
  • noRollbackForі noRollbackForClassName: список Exceptionкласів Java, які можна запустити, не викликаючи відкат транзакцій
  • rollbackForі rollbackForClassName: список Exceptionкласів Java, які викликають відкат транзакцій під час перекидання
  • propagation: тип розповсюдження транзакцій, наданий PropagationEnum. Наприклад, якщо контекст транзакції може бути успадкований (наприклад, REQUIRED) або новий контекст транзакції повинен бути створений (наприклад, REQUIRES_NEW) або якщо виняток повинен бути викинутий, якщо немає контексту транзакції (наприклад, MANDATORY) або якщо виняток повинен бути викинутий якщо знайдено поточний контекст транзакції (наприклад, NOT_SUPPORTED).
  • readOnly: чи повинна поточна транзакція читати дані лише без змін.
  • timeout: через скільки секунд слід дозволити запускати контекст транзакції, поки не буде викинуто виняток із тайм-ауту.
  • valueабо transactionManager: назва Spring TransactionManagerBean, що використовується для прив'язки контексту транзакції.

Java EE @Transactional

javax.transaction.TransactionalАнотацій була додана в специфікації Java EE 7 (близько 2013 року ). Так, анотація Java EE була додана через 8 років, що є її аналогом Spring.

Java EE @Transactionalвизначає лише 3 атрибути:

  • dontRollbackOn: список Exceptionкласів Java, які можна запустити, не викликаючи відкат транзакцій
  • rollbackOn: список Exceptionкласів Java, які викликають відкат транзакцій при перекиданні
  • value: стратегія поширення, надана TxTypeЕнумом. Наприклад, якщо контекст транзакції може бути успадкований (наприклад, REQUIRED) або новий контекст транзакції повинен бути створений (наприклад, REQUIRES_NEW) або якщо виняток повинен бути викинутий, якщо немає контексту транзакції (наприклад, MANDATORY) або якщо виняток повинен бути викинутий якщо знайдено поточний контекст транзакції (наприклад, NOT_SUPPORTED).

Який вибрати?

Якщо ви використовуєте Spring або Spring Boot, використовуйте @Transactionalанотацію Spring , оскільки вона дозволяє налаштувати більше атрибутів, ніж @Transactionalанотація Java EE .

Якщо ви використовуєте Java EE поодинці і розгортаєте свою програму на сервері додатків Java EE, тоді використовуйте примітку Java EE `@ @ Transactional`.

Детальніше про те, як відрізняється конфігурація рівня ізоляції при використанні визначення Spring або Java EE @Transactional, ознайомтеся з цією статтею .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.