Overview of transaction propagation strategies in Spring and Jakarta EE.

Photo by Luis Fernando Felipe Alves, https://unsplash.com/photos/dVBs3hKQrNo

Both Spring and Jakarta EE allow for convenient, annotation-based transaction demarcation with the following annotations:

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?

  1. Continue using the existing transaction, and don't create a new one (REQUIRED, SUPPORTS, MANDATORY).
  2. Suspend the existing transaction, and
    1. create a new, inner transaction (REQUIRES_NEW).
    2. don't create a new transaction (NOT_SUPPORTED).
  3. Create a savepoint for the existing transaction, and create a nested transaction (NESTED).
  4. 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?

  1. Create a new one (REQUIRED, REQUIRES_NEW, NESTED).
  2. Don't create a new one (SUPPORTS, NOT_SUPPORTED, NEVER).
  3. Throw an exception (MANDATORY)

Overview table

Spring Jakarta EE existing TX no existing TX
REQUIRED REQUIRED use create
SUPPORTS SUPPORTS use don’t create
MANDATORY MANDATORY use exception
REQUIRES_NEW REQUIRES_NEW suspend & create create
NOT_SUPPORTED NOT_SUPPORTED suspend don’t create
NESTED - savepoint & inner TX create
NEVER NEVER exception don’t create