Applicability and Interchangeability JTA Transactional annotation applies to CDI-managed beans and classes defined as managed beans by the Java EE specification, whereas Spring's Transactional annotation applies only to Spring beans.
The @Transactional annotation makes use of the attributes rollbackFor or rollbackForClassName to rollback the transactions, and the attributes noRollbackFor or noRollbackForClassName to avoid rollback on listed exceptions. The default rollback behavior in the declarative approach will rollback on runtime exceptions.
Transactional annotation provides the application the ability to declaratively control transaction boundaries on CDI managed beans, as well as classes defined as managed beans by the Java EE specification, at both the class and method level where method level annotations override those at the class level.
Spring has defined its own Transactional annotation to make Spring bean methods transactional, years ago.
Java EE 7 has finally done the same thing and now allows CDI bean methods to be transactional, in addition to EJB methods. So since Java EE 7, it also defines its own Transactional annotation (it obviously can't reuse the Spring one).
In a Java EE 7 application, you'll use the Java EE annotation.
In a Spring application, you'll use the Spring annotation.
Their use is the same: informing the container (Java EE or Spring) that a method is transactional.
Another difference is how Spring handles the @Transactional annotations
javax.ejb.TransactionAttribute
is available in the classpath (from version 2.5.3 to 3.2.5).
Thus you can end up with your annotations not being taken into account if only javax.transaction.Transactional
is in your classpath and not javax.ejb.TransactionAttribute
.
This can be the case if you're working with Hibernate: hibernate-core (4.3.7.Final) depends on jboss-transaction-api_1.2_spec (1.0.0.Final), which doesn't provide javax.ejb.TransactionAttribute
.Please be careful, (this issue happened in tomcat),
If your application is SPRING web application and you are using Spring's transaction handling mechanism that is @org.springframework.transaction.annotation.Transactional
, then don't mix it with javax.transaction.Transactional.
That is Always use, @org.springframework.transaction.annotation.Transactional
in a spring application consistently.
Otherwise we may end up with this error,
org.springframework.orm.jpa.JpaSystemException: commit failed; nested exception is org.hibernate.TransactionException: commit failed
........
Caused by: java.sql.SQLException: Protocol violation: [0]
Both the Spring and JPA @Transaction
annotation allow you to define the scope of a given application transaction.
So, if a service method is annotated with the @Transactional
annotation, it will run in a transactional context. If the service method uses multiple DAO or Repositories, all read and write operations will be executed in the same database transaction.
@Transactional
The org.springframework.transaction.annotation.Transactional
annotation has been available since the 1.2 version of the Spring framework (circa 2005), and it allows you to set the following transactional properties:
isolation
: the underlying database isolation levelnoRollbackFor
and noRollbackForClassName
: the list of Java Exception
classes that can be triggered without triggering a transaction rollbackrollbackFor
and rollbackForClassName
: the list of Java Exception
classes that trigger a transaction rollback when being thrownpropagation
: the transaction propagation type given by the Propagation
Enum. For instance, if the transaction context can be inherited (e.g., REQUIRED
) or a new transaction context should be created (e.g., REQUIRES_NEW
) or if an exception should be thrown if no transaction context is present (e.g., MANDATORY
) or if an exception should be thrown if a current transaction context is found (e.g., NOT_SUPPORTED
).readOnly
: whether the current transaction should only read data without applying any changes.timeout
: how many seconds should the transaction context be allowed to run until a timeout exception is thrown.value
or transactionManager
: the name of the Spring TransactionManager
bean to be used when binding the transaction context.@Transactional
The javax.transaction.Transactional
annotation was added by the Java EE 7 specification (circa 2013). So, the Java EE annotation was added 8 years later than its Spring counterpart.
The Java EE @Transactional
defines just 3 attributes:
dontRollbackOn
: the list of Java Exception
classes that can be triggered without triggering a transaction rollbackrollbackOn
: the list of Java Exception
classes that trigger a transaction rollback when being thrownvalue
: the propagation strategy, given by the TxType
Enum. For instance, if the transaction context can be inherited (e.g., REQUIRED
) or a new transaction context should be created (e.g., REQUIRES_NEW
) or if an exception should be thrown if no transaction context is present (e.g., MANDATORY
) or if an exception should be thrown if a current transaction context is found (e.g., NOT_SUPPORTED
).If you're using Spring or Spring Boot, then use the Spring @Transactional
annotation, as it allows you to configure more attributes than the Java EE @Transactional
annotation.
If you are using Java EE alone, and you deploy your application on a Java EE application server, then use the Java EE @Transactional
annotation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With