Spring vs. Jakarta EE: Transaction Propagation
Overview of transaction propagation strategies in Spring and Jakarta EE.
Both Spring and Jakarta EE allow for convenient, annotation-based transaction demarcation with the following annotations:
- Spring: @Transactional
- Jakarta EE: @Transactional, or @Stateless with EJBs
By using values of the Spring enum Propagation, or the Jakarta EE enums Transactional.TxType / TransactionAttributeType (EJB), the following aspects regarding transaction propagation can be configured:
What shall happen if there already is a running transaction?
- Continue using the existing transaction, and don't create a new one (REQUIRED, SUPPORTS, MANDATORY).
- Suspend the existing transaction, and
- create a new, inner transaction (REQUIRES_NEW).
- don't create a new transaction (NOT_SUPPORTED).
- Create a savepoint for the existing transaction, and create a nested transaction (NESTED).
- Throw an exception (NEVER).
An “inner” transaction differs from a “nested” transaction in the following way: Inner transactions are completely independent from the outer transaction. As soon as the inner transaction finishes successfully, it is committed to the database. In contrast, nested transactions are part of the outer transaction, and are committed at the end of the outer transaction. If the outer transaction fails, the nested transaction fails as well. Nested transactions are not supported by all transaction managers.
What shall happen if there is no running transaction?
- Create a new one (REQUIRED, REQUIRES_NEW, NESTED).
- Don't create a new one (SUPPORTS, NOT_SUPPORTED, NEVER).
- Throw an exception (MANDATORY)
|Spring||Jakarta EE||existing TX||no existing TX|
|REQUIRES_NEW||REQUIRES_NEW||suspend & create||create|
|NESTED||-||savepoint & inner TX||create|