🗃️ JPA Q21 / 63

What are transactional propagation types in Spring and what are their use cases?

AI-Powered Answer ✓ Answered

In Spring, transactional propagation types define how a transactional method behaves when called from another transactional method or when initiating a new transaction. They govern the scope of the physical transaction, ensuring data consistency and integrity.

Understanding Transactional Propagation

Transactional propagation in Spring determines how transactional boundaries are managed when multiple transactional methods interact. It dictates whether a method should join an existing transaction, create a new one, or execute non-transactionally. This is crucial for maintaining data consistency across complex business operations.

Key Transactional Propagation Types and Their Use Cases

REQUIRED (Default)

If a transaction already exists, the method joins it. If not, a new transaction is created. This is the most common propagation type and often the appropriate choice for most business operations.

Use Case: Suitable for most service layer operations where business logic should run within a transaction, and nested calls should share the same transaction context to ensure atomicity across multiple operations (e.g., creating a user and their default settings).

SUPPORTS

If a transaction already exists, the method runs within it. If no transaction exists, the method runs non-transactionally.

Use Case: Useful for read-only operations or optional transactional behavior where the method can benefit from an existing transaction but does not strictly require one. For instance, a logging service that might be called from both transactional and non-transactional contexts.

MANDATORY

The method must be executed within an existing transaction. If no transaction is active, an IllegalTransactionStateException is thrown.

Use Case: Ensures that a method is always part of a larger, already-defined transaction. This is useful for critical operations that absolutely depend on an active transaction context to maintain data integrity, typically invoked by another transactional method.

NEVER

The method must not be executed within an existing transaction. If a transaction is active, an IllegalTransactionStateException is thrown. The method always runs non-transactionally.

Use Case: For operations that must explicitly run outside any transaction, such as sending emails, publishing events to an external system, or updating non-transactional caches, especially when these actions should not be rolled back with the main transaction.

NOT_SUPPORTED

The method always runs non-transactionally. If a transaction is active, it is suspended before the method executes and resumed after the method completes.

Use Case: Similar to NEVER, but allows the method to temporarily suspend an existing transaction. This is useful for operations that should not participate in a transaction but are less strict than NEVER, such as logging or certain cache updates that should happen regardless of the calling transaction's outcome.

REQUIRES_NEW

Always creates a new, independent transaction. If a transaction is already active, it is suspended before the new transaction is started, and resumed after the new transaction completes. The new transaction has its own commit/rollback scope, independent of the calling transaction.

Use Case: For operations that need to be committed or rolled back independently of the calling transaction. For example, logging audit trails, sending critical notifications, or persisting retry attempts, where the success/failure of this specific operation should not affect or be affected by the main transaction.

NESTED

If a transaction is active, it creates a nested transaction (a "savepoint" in JDBC). If no transaction is active, it behaves like REQUIRED. A nested transaction can commit or roll back independently of its parent, but its commit is only truly finalized when the parent commits. A rollback of the parent transaction will roll back the nested transaction as well.

Use Case: Allows partial rollbacks within a larger transaction. This is often used for operations that might fail but shouldn't cause the entire parent transaction to fail, allowing the parent to catch the exception and continue. Requires a JDBC 3.0 driver or JTA transaction manager supporting savepoints.

Summary of Propagation Types

Propagation TypeBehavior with Existing TransactionBehavior without Existing TransactionCommon Use Case
REQUIREDJoins existingCreates newMost business logic operations (default)
SUPPORTSJoins existingExecutes non-transactionallyRead-only operations, optional transactional
MANDATORYThrows exceptionThrows exceptionCritical operations requiring existing transaction
NEVERThrows exceptionExecutes non-transactionallyOperations that must always be non-transactional
NOT_SUPPORTEDSuspends existingExecutes non-transactionallyLogging, external calls that shouldn't participate
REQUIRES_NEWSuspends existing, creates newCreates newIndependent commit/rollback operations (e.g., audit logging)
NESTEDCreates nested (savepoint)Creates newPartial rollbacks within a larger transaction