I. Classification of communication behavior of transactions
According to the spring source of org. Springframework. Transaction. The annotation. The Propagation enumerated in the class definition, a total of 7 Propagation behavior:
Classification of communication behavior | instructions |
---|---|
REQUIRED (Default propagation behavior) | 1, use the current transaction, if there is no transaction, will create a new transaction The child method also runs in the parent method’s transaction, and if the child method has a transaction, it will join the parent method’s transaction |
SUPPORTS | If a transaction exists, use it. Do not use if no transaction currently exists |
MANDATORY | When the transaction propagation behavior of a method is set to MANDATORY, a transaction must exist when the method is called by any other method or an exception is thrown |
REQUIRES_NEW | 1. If there is a transaction, suspend the current transaction and create a new transaction for your own use 2. If there is no transaction, create a new transaction |
NOT_SUPPORTED | Transactions are not used regardless of whether or not they are currently being used |
NEVER | Does not use transactions and throws an exception if the caller currently has a transaction |
NESTED | Start a subtransaction (belonging to a nested transaction) that is committed or rolled back independently |
Two, brief example
Some common or easily confused propagation behaviors are described in the following pseudocodes:
REQUIRED
1. There is no transaction in the parent method, and there is no transaction in the child method
class parentClass {
// The parent method has no transactions
void parentMethod(a){
// call the child method in the parent methodsubClass.subMethod(); . }}class subClass {
// There are no transactions in the submethods
void subMethod(a){... }}Copy the code
In this case, none of the data in the child and parent methods is rolled back after an exception occurs
2, there is a transaction in the parent method, there is no transaction in the child method
class parentClass {
// The parent method has a transaction
@Transactional(propagation = Propagation.REQUIRED)
void parentMethod(a){
// call the child method in the parent methodsubClass.subMethod(); . }}class subClass {
// There are no transactions in the submethods
void subMethod(a){... }}Copy the code
In this case, the parent method’s transaction is passed to the child method, so whenever an exception occurs in the child parent method, the data is rolled back
3, there is no transaction in the parent method, there is a transaction in the child method
class parentClass {
// There is no transaction in the parent method
void parentMethod(a){
// call the child method in the parent methodsubClass.subMethod(); . }}class subClass {
// There is a transaction in the submethod
@Transactional(propagation = Propagation.REQUIRED)
void subMethod(a){... }}Copy the code
- In this case, if an exception occurs in a child method, data in the child method is rolled back, but data in the parent method is not rolled back
- If the parent method fails after the child method completes execution, the child method’s data will not be rolled back because the transaction has already been committed. The parent method’s data is also not rolled back because the parent method has no transactions
4, there are transactions in the parent method, there are transactions in the child method
class parentClass {
// There are transactions in the parent method
@Transactional(propagation = Propagation.REQUIRED)
void parentMethod(a){
// call the child method in the parent methodsubClass.subMethod(); . }}class subClass {
// Transactions also exist in submethods
@Transactional(propagation = Propagation.REQUIRED)
void subMethod(a){... }}Copy the code
In this case, the child method joins the parent method’s transaction, so whenever an exception occurs in the child parent method, the data is rolled back
MANDATORY
1. The parent method does not have a transaction
class parentClass {
// There is no transaction in the parent method
void parentMethod(a){
// call the child method in the parent methodsubClass.subMethod(); . }}class subClass {
// There is a transaction in the submethod
@Transactional(propagation = Propagation.MANDATORY)
void subMethod(a){... }}Copy the code
In this case, the parent method directly throws an exception when calling the child method because the parent method has no transactions
The parent method has a transaction
class parentClass {
// There are transactions in the parent method
@Transactional(propagation = Propagation.REQUIRED)
void parentMethod(a){
// call the child method in the parent methodsubClass.subMethod(); . }}class subClass {
// Transactions also exist in submethods
@Transactional(propagation = Propagation.MANDATORY)
void subMethod(a){... }}Copy the code
In this case, when the parent method calls the child method, there is a transaction, so no exception is thrown. The parent method’s transaction is passed to the child method, so whenever an exception occurs in the child parent method, the data is rolled back
REQUIRES_NEW
1. There is no transaction in the parent method
class parentClass {
// There is no transaction in the parent method
void parentMethod(a){
// call the child method in the parent methodsubClass.subMethod(); . }}class subClass {
// There is a transaction in the submethod
@Transactional(propagation = Propagation.REQUIRES_NEW)
void subMethod(a){... }}Copy the code
In this case, if an exception occurs in a child method, the child method’s data is rolled back. Data in the parent method is not rolled back
2. There are transactions in the parent method
class parentClass {
// There are transactions in the parent method
@Transactional(propagation = Propagation.REQUIRES)
void parentMethod(a){
// call the child method in the parent methodsubClass.subMethod(); . }}class subClass {
// There is a transaction in the submethod
@Transactional(propagation = Propagation.REQUIRES_NEW)
void subMethod(a){... }}Copy the code
In this case, note:
- If an exception occurs in a child method, the child method’s data is rolled back, the child method’s exception is passed to the parent method, and the parent method’s data is rolled back
- If there is no exception in the child method, but the parent method has an exception after executing the child method, only the parent method’s data will be rolled back. The child method’s data will not be rolled back because the child method’s transaction has already committed
NESTED
Emphasize the difference between nested-desktop and REQUIRED: The pseudocode is shown below:
1. Both parent methods are Propagation.REQUIRED
class ParentClass {
@Transactional(propagation = Propagation.REQUIRED)
public void parentMethod(a) {
// The parent method inserts data
stuMapper.insertSelective("Parent method inserts data");
// Call the child methodsubClass.subMethod(); }}class SubClass {
@Transactional(propagation = Propagation.REQUIRED)
public void subMethod(a) {
// Insert data
stuMapper.insertSelective("Submethod inserts data");
int i = 1 / 0; }}Copy the code
In this case, subMethod() is added to the parentMethod() transaction, and if subMethod() fails, the entire transaction is rolled back
2, The submethod is Propagation.NESTED
class ParentClass {
@Transactional(propagation = Propagation.REQUIRED)
public void parentMethod(a) {
// The parent method inserts data
stuMapper.insertSelective("Parent method inserts data");
// Call the child method
try {
ParentMethod () is not rolled back if subMethod() is abnormal. The nested transaction is rolled back independently
subClass.subMethod();
} catch (Exception e) {
// Prints logs
}
// Continue with the other methods}}class SubClass {
@Transactional(propagation = Propagation.NESTED)
public void subMethod(a) {
// Insert data
stuMapper.insertSelective("Submethod inserts data");
int i = 1 / 0; }}Copy the code
In this case, subMethod() starts a nested transaction, and if subMethod() fails, the parentMethod() transaction will not be rolled back because the nested transaction will be rolled back independently.