Spring's propagation types for the
@Transactional annotation differ in how they behave in presence/absence of an existing transaction:
|PROPAGATION TYPE||no current transaction||there's a current transaction|
||throw exception||use current transaction|
||don't create a transaction, run method outside any transaction||throw exception|
||don't create a transaction, run method outside any transaction||suspend current transaction, run method outside any transaction|
||don't create a transaction, run method outside any transaction||use current transaction|
||create a new transaction||use current transaction|
||create a new transaction||suspend current transaction, create a new independent transaction|
||create a new transaction||create a new nested transaction|
It could be argued that
NOT_SUPPORTED (and arguably
SUPPORTS also) don't serve any useful purpose, and exist only for completeness; after all, why would you want to explicitly run something outside of any transaction?
As for the other propagation types,
SUPPORTS would be used when you want your code to be part of the current transaction, sharing its commit/rollback fate;
NESTED would come into use in cases where you want to be able to rollback only parts of a bigger transaction; and finally
REQUIRES_NEW is to be used when you want to do something totally unrelated to the current transaction.
The difference between
SUPPORTS strives in how they behave when there is no existing transaction.
MANDATORY acts as a sort of
assert directive, ensuring there is an opened transaction.
REQUIRED creates a new transaction, being safe to use outside any transaction.
SUPPORTS rides along an existing transaction, but doesn't create a new one if none exists.