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


153

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

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

Спасибо за ответы.

Ответы:


125

Spring определил собственную аннотацию Transactional, чтобы сделать методы Spring bean транзакционными много лет назад.

Java EE 7 наконец-то сделала то же самое и теперь позволяет использовать методы EJB-компонентов в дополнение к EJB-методам. Таким образом, начиная с Java EE 7, он также определяет свою собственную аннотацию Transactional (очевидно, она не может повторно использовать Spring).

В приложении Java EE 7 вы будете использовать аннотацию Java EE.

В приложении Spring вы будете использовать аннотацию Spring.

Их использование одинаково: информирование контейнера (Java EE или Spring) о том, что метод является транзакционным.


28
Более того: для того, чтобы управлять юниверсом, Spring также добавил неявную поддержку, javax.transaction.Transactionalтак что теперь его можно использовать и в приложениях Spring без каких-либо дополнительных действий. IMO, это было довольно плохое решение с точки зрения дизайна , потому что из моего опыта многие разработчики неосознанно путают эти два в своем коде, что впоследствии приводит к проблемам.
Юрий Наконечный

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 -action-api_1.2_spec (1.0.0.Final), который не предоставляет javax.ejb.TransactionAttribute.


его не всегда берут, если, к примеру, его не используют в приватном методе.
Strash

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
Примечание: этот ответ является частным случаем моего ответа
Jidehem

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: имя TransactionManagerbean-компонента Spring, который будет использоваться при привязке контекста транзакции.

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: стратегия распространения, данная TxTypeEnum. Например, если контекст транзакции может быть унаследован (например, 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.