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

152

Não entendo qual é a diferença real entre anotações javax.transaction.Transactionale org.springframework.transaction.annotation.Transactional?

É org.springframework.transaction.annotation.Transactionaluma extensão javax.transaction.Transactionalou eles têm um significado totalmente diferente? Quando cada um deles deve ser usado? Primavera @Transactinalna camada de serviço e javax no DAO?

Obrigado por responder.

estames
fonte

Respostas:

125

O Spring definiu sua própria anotação Transacional para tornar os métodos do bean Spring transacionais, anos atrás.

O Java EE 7 finalmente fez a mesma coisa e agora permite que os métodos do bean CDI sejam transacionais, além dos métodos EJB. Portanto, desde o Java EE 7, ele também define sua própria anotação Transacional (obviamente não pode reutilizar a Spring).

Em um aplicativo Java EE 7, você utilizará a anotação Java EE.

Em um aplicativo Spring, você usará a anotação Spring.

Seu uso é o mesmo: informar ao contêiner (Java EE ou Spring) que um método é transacional.

JB Nizet
fonte
28
Mais do que isso: para governar o universo, o Spring também adicionou suporte implícito para javax.transaction.Transactionalque agora você pudesse usá-lo também em aplicativos Spring sem nenhuma ação adicional. Na IMO, essa foi uma péssima decisão do ponto de vista do design , porque, pela minha experiência, muitos desenvolvedores confundem inconscientemente esses dois em seu código, o que gera problemas posteriormente.
Yuriy Nakonechnyy 31/10
16
Além disso, org.springframework.transaction.annotation.Transactionaloferece mais opções (como readOnly, timeout) quejavax.transaction.Transactional
pierrefevrier
1
@yura, que problemas você observou?
Lee Chee Kiam
1
@LeeCheeKiam, veja duas respostas abaixo
Yuriy Nakonechnyy
50

Outra diferença é como o Spring lida com as anotações @Transactional

  • org.springframework.transaction.annotation.Transactional é sempre levado em consideração
  • javax.transaction.Transactional é levado em consideração apenas quando transações EJB3 estão presentes. A presença de transações EJB3 é feita verificando se a classe javax.ejb.TransactionAttributeestá disponível no caminho de classe (da versão 2.5.3 a 3.2.5). Assim, você pode terminar com suas anotações não sendo levadas em consideração se javax.transaction.Transactionalestiver apenas no seu caminho de classe e não javax.ejb.TransactionAttribute. Este pode ser o caso se você estiver trabalhando com o Hibernate: hibernate-core (4.3.7.Final) depende do jboss-transaction-api_1.2_spec (1.0.0.Final), que não fornece javax.ejb.TransactionAttribute.
Jidehem
fonte
9
Eu acho que isso não é um problema mais com Spring 4.2.0: javax.transaction.Transactional anotação também é suportado como um substituto para próprio anotação da Primavera
v Arend Reinersdorff.
nem sempre é usado, se estiver em um método privado, por exemplo, não será usado.
strash
36

Tenha cuidado, (esse problema ocorreu no tomcat),

Se o seu aplicativo for um aplicativo da Web SPRING e você estiver usando o mecanismo de manipulação de transações do Spring @org.springframework.transaction.annotation.Transactional, não misture com javax.transaction.Transactional.

Isso é sempre usar, @org.springframework.transaction.annotation.Transactionalem uma aplicação de mola de forma consistente.

Caso contrário, podemos acabar com este erro,

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
fonte
1
Nota: esta resposta é um caso especial da minha resposta
Jidehem 9/17
3

Escopo da transação declarativa

As @Transactionanotações Spring e JPA permitem definir o escopo de uma determinada transação de aplicativo.

Portanto, se um método de serviço for anotado com a @Transactionalanotação, ele será executado em um contexto transacional. Se o método de serviço usar vários DAO ou Repositórios, todas as operações de gravação e gravação de anúncios serão executadas na mesma transação do banco de dados.

Primavera @Transactional

A org.springframework.transaction.annotation.Transactionalanotação está disponível desde a versão 1.2 da estrutura Spring (por volta de 2005) e permite definir as seguintes propriedades transacionais:

  • isolation: o nível de isolamento do banco de dados subjacente
  • noRollbackFore noRollbackForClassName: a lista de Exceptionclasses Java que podem ser acionadas sem acionar uma reversão de transação
  • rollbackFore rollbackForClassName: a lista de Exceptionclasses Java que acionam uma reversão de transação ao serem lançadas
  • propagation: o tipo de propagação da transação fornecido pelo PropagationEnum. Por exemplo, se o contexto da transação pode ser herdado (por exemplo, REQUIRED) ou um novo contexto de transação deve ser criado (por exemplo, REQUIRES_NEW) ou se uma exceção deve ser lançada se nenhum contexto de transação estiver presente (por exemplo, MANDATORY) ou se uma exceção deve ser lançada se um contexto de transação atual for encontrado (por exemplo, NOT_SUPPORTED).
  • readOnly: se a transação atual deve apenas ler os dados sem aplicar nenhuma alteração.
  • timeout: quantos segundos o contexto da transação deve ser executado até que uma exceção de tempo limite seja lançada.
  • valueou transactionManager: o nome do TransactionManagerbean Spring a ser usado ao vincular o contexto da transação.

Java EE @Transactional

A javax.transaction.Transactionalanotação foi adicionada pela especificação Java EE 7 (por volta de 2013). Portanto, a anotação Java EE foi adicionada 8 anos depois à sua contraparte Spring.

O Java EE @Transactionaldefine apenas três atributos:

  • dontRollbackOn: a lista de Exceptionclasses Java que podem ser acionadas sem acionar uma reversão de transação
  • rollbackOn: a lista de Exceptionclasses Java que acionam uma reversão de transação ao serem lançadas
  • value: a estratégia de propagação, dada pelo TxTypeEnum. Por exemplo, se o contexto da transação pode ser herdado (por exemplo, REQUIRED) ou um novo contexto de transação deve ser criado (por exemplo, REQUIRES_NEW) ou se uma exceção deve ser lançada se nenhum contexto de transação estiver presente (por exemplo, MANDATORY) ou se uma exceção deve ser lançada se um contexto de transação atual for encontrado (por exemplo, NOT_SUPPORTED).

Qual escolher?

Se você estiver usando Spring ou Spring Boot, use a @Transactionalanotação Spring , pois ela permite configurar mais atributos que a @Transactionalanotação Java EE .

Se você estiver usando o Java EE sozinho e implantar seu aplicativo em um servidor de aplicativos Java EE, use a anotação `` @ Transactional` do Java EE.

Para obter mais detalhes sobre como a configuração do nível de isolamento é diferente ao usar as @Transactionaldefinições Spring ou Java EE , consulte este artigo .

Vlad Mihalcea
fonte