Into Transaction page, you may read about all typical transaction usage.
But, sometime, even this is not enought.
To cover the most sophisticated cases, you may need to use propagations.
There are few of them:
Support a current transaction, throw an exception if none exists.
Does not start a new Transaction, just checks whether a transaction is active
Execute within a nested transaction if a current transaction exists, behave like PROPAGATION_REQUIRED else.
Start a nested transaction if a transaction exists, start a new transaction otherwise.
Execute non-transactionally, throw an exception if a transaction exists.
Does not start a transaction. Fails if a transaction is present.
Execute non-transactionally, suspend the current transaction if one exists.
Does not start a transaction. Suspends any existing transaction.
Support a current transaction, create a new one if none exists.
If a transaction exists, use that, if not, create a new one. In 95% of cases, this is what you need.
Create a new transaction, suspend the current transaction if one exists.
Always creates a new transaction, no matter if an existing transaction is present. If there is, it will be suspended for the duration of this method execution.
Support a current transaction, execute non-transactionally if none exists.
Can use a transaction if one is present, but doesn't need one (and won't start a new one either)
Every no-arg execute() uses SUPPORTS propagation. That mean, if you already opened a transaction, it will be used. Otwerwise, a new transaction will be opened.
However, there is also an execute(Propagation propagation) method where you are able to specify the propagation.
Example:
Update will be executed irrespective of main transaction ending.