introduction
In this blog post, the ape is mainly aimed at the application of transactions, and there are seven types of communication behaviors of transactions. These seven communication behaviors have different application scenarios. The following ape will discuss the respective characteristics of the seven communication behaviors
Functional relationship
REQUIED
/** * Support a current transaction, create a new one if none exists. * Analogous to EJB transaction attribute of the same name. * <p>This is the default setting of a transaction annotation. */ REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED),
case1
The last sentence in the above figure is not well written. It should be that the two children methods failed to execute and save, rather than not executing.
case2
Although a transaction is added to function 2 in the above figure, it should be that there is already a transaction in function 1 and the propagation behavior is required. This shows that when function 2 is executed and function 1 already exists, it will directly add the transaction of function 1 and will not create a new transaction. This phenomenon is the propagation of the required transaction. At this time, it doesn't matter whether the function has a transaction annotation or not, All child transactions will be added to the parent transaction. According to the atomicity of the transaction, the transaction of function 1 is adopted at this time. If an exception occurs in the middle, the execution of all transactions fails.
Full rollback.
The communication behavior of require can be summarized as that when the boss has food to eat, I rub the food to eat, and when the boss has no food to eat, I buy it myself.
support
The source code of support is shown below
/** * Support a current transaction, execute non-transactionally if none exists. * Analogous to EJB transaction attribute of the same name. * <p>Note: For transaction managers with transaction synchronization, * {@code SUPPORTS} is slightly different from no transaction at all, * as it defines a transaction scope that synchronization will apply for. * As a consequence, the same resources (JDBC Connection, Hibernate Session, etc) * will be shared for the entire specified scope. Note that this depends on * the actual synchronization configuration of the transaction manager. * @see org.springframework.transaction.support.AbstractPlatformTransactionManager#setTransactionSynchronization */ SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS),
case1
There are no records in the database
case2
It can be concluded that if the boss has food, I will rub it, and if the boss has no food, I will go on hunger strike. Generally speaking, supports is used to query business.
MANDATORY
Let's look at the source code first
/** * Support a current transaction, throw an exception if none exists. * Analogous to EJB transaction attribute of the same name. */ MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY),
If there is no transaction at present, an exception will be thrown directly.
case1
case2
MANDATORY can be summarized as: if the boss doesn't give me food, I'll go on strike
REQUIRES_NEW
/** * Create a new transaction, and suspend the current transaction if one exists. * Analogous to the EJB transaction attribute of the same name. * <p><b>NOTE:</b> Actual transaction suspension will not work out-of-the-box * on all transaction managers. This in particular applies to * {@link org.springframework.transaction.jta.JtaTransactionManager}, * which requires the {@code javax.transaction.TransactionManager} to be * made available to it (which is server-specific in standard Java EE). * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager */ REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW),
case1
case2
case3
REQUIRES_NEW can be summarized as: the meal given by the boss is too bad. I want to order my own meal. If the boss doesn't give me food, I want to order my own meal
NOT_SUPPORTED
/** * Execute non-transactionally, suspend the current transaction if one exists. * Analogous to EJB transaction attribute of the same name. * <p><b>NOTE:</b> Actual transaction suspension will not work out-of-the-box * on all transaction managers. This in particular applies to * {@link org.springframework.transaction.jta.JtaTransactionManager}, * which requires the {@code javax.transaction.TransactionManager} to be * made available to it (which is server-specific in standard Java EE). * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager */ NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED),
Suspend the current transaction when a transaction is encountered.
case1
case2
test result
NOT_SUPPORTED can be summarized as: I'm too busy to eat the meal given by my boss.
NEVER
/** * Execute non-transactionally, throw an exception if a transaction exists. * Analogous to EJB transaction attribute of the same name. */ NEVER(TransactionDefinition.PROPAGATION_NEVER),
case1
case2
NEVER can be summarized as that the boss was so disgusting that he forced me to go on strike.
NESTED
/** * Execute within a nested transaction if a current transaction exists, * behave like {@code REQUIRED} otherwise. There is no analogous feature in EJB. * <p>Note: Actual creation of a nested transaction will only work on specific * transaction managers. Out of the box, this only applies to the JDBC * DataSourceTransactionManager. Some JTA providers might support nested * transactions as well. * @see org.springframework.jdbc.datasource.DataSourceTransactionManager */ NESTED(TransactionDefinition.PROPAGATION_NESTED);
case1
The parent transaction exception affects the submission of child transactions.
The child transaction exception will also affect the submission of the parent transaction.
case2
After adding a savepoint, the child transaction will not affect the commit of the parent transaction.
Test results:
NESTED can be summarized as that if the boss makes a wrong decision, the boss will blame him. If he has no food, I will suffer with him; I didn't work properly. The boss immediately got rid of the crime and had food to eat. He was so tired that he didn't have food to eat
summary
- REQUIRED: use the current transaction. If there is no transaction at present, create a new transaction by yourself. The sub method must run in a transaction;
If there is a current transaction, join the transaction as a whole. - SUPPORTS: if there is a transaction currently, the transaction is used; If there are currently no transactions, no transactions are used.
- MANDATORY: this propagation attribute enforces the existence of a transaction. If it does not exist, an exception will be thrown
- REQUIRES_NEW: if there is a current transaction, suspend the transaction and create a new transaction for your own use;
If there is no current transaction, the same as REQUIRED - NOT_SUPPORTED: if there is a transaction at present, suspend the transaction. It is not applicable to the transaction to run the database operation
- NEVER: throw an exception if a transaction currently exists
- NESTED: if there is a transaction currently, the sub transaction (NESTED transaction) will be opened. The NESTED transaction is committed or rolled back independently;
If there is no current transaction, the same as REQUIRED.
However, if the primary transaction is committed, it will be committed with the secondary transaction.
If the main transaction is rolled back, the sub transactions are rolled back together. On the contrary, if the child transaction is abnormal, the parent transaction can be rolled back or not.