Introduction to Transaction propagation

Transaction propagation is designed to address transaction support for methods when they are executed in a nested manner

We know that the transaction can effectively guarantee the consistency of the data, will not transfer the money when all of a sudden power failure, you have less money in the account, but it does not increase the target of the money in the account of the situation (here, your account money decreases, the target increase money account, in the same transaction), but if all the methods are carried out in the form of the transaction, The performance of the database will be greatly reduced, so we only perform the operations related to data changes (insert, update, delete) in a transactional manner to ensure data consistency. The most common database operations, queries, are not performed in a transactional manner.

But what if transaction-enabled methods are nested with other methods that might support transactions? (In other words: If the current method already has a transaction, but other methods are called in that method that may also support transactions, how does the database handle the execution of those methods?)

Transaction propagation is used to solve this problem.

Transaction propagation type and description:

Transaction propagation type instructions
PROPAGATION_REQUIRED If there is no transaction, create a new one. If there is an existing transaction, join the transaction
PROPAGATION_SUPPORTS Transactions are supported and executed nontransactionally if there is no transaction currently in place
PROPAGATION_MANDATORY Using the current transaction, an exception mandatory is thrown if there is no transaction currently
PROPAGATION_REQUIRES_NEW Create a new transaction. If one exists, suspend the current transaction and execute it in the new transaction
PROPAGATION_NOT_SUPPORTED Transactions are not supported and are suspended if one currently exists
PROPAGATION_NEVER Executes nontransactionally, throwing an exception if a transaction currently exists
PROPAGATION_NESTED Nested transactions, executed in a nested transaction if one currently exists. If no transaction currently exists, an operation similar to PROPAGATION_REQUIRED is performed

The bold sections are the three transaction propagation types we use most in our actual work. And that’s the type we’re going to introduce.

Transaction propagation explanation:

We now have a requirement to execute two methods batchInsert_A() and batchInsert_B() for batch inserts. We create a method batchInsert() to nest the two methods and execute:

@Transactional(propagation=PROPAGATION.REQUIRED)
private void batchInsert_A(a){... insert ... }@Transactional(propagation=PROPAGATION.REQUIRED)
private void batchInsert_B(a){... insert ... }@Transactional(propagation=PROPAGATION.REQUIRED)
public void batchInsert(a) {
    batchInsert_A();
    // throw new RuntimeException(" RuntimeException ");
    batchInsert_B();
}
Copy the code

PROPAGATION_REQUIRED:

Here all three method transaction propagation types are PROPAGATION_REQUIRED

Step 1: When the batchInsert() method is executed, its transaction propagation type is set to PROPAGATION_REQUIRED, and since there are no transactions currently, a new transaction is created and batchInsert() executes within that transaction.

Step 2: When batchInsert_A() is executed, its transaction propagation type is set to PROPAGATION_REQUIRED. Since there are already transactions, this method is added to the transaction created by batchInsert(),

Step 3: Similarly, batchInsert_B() is added to the transaction. Because all three methods are in the same transaction, if a runtime exception occurs during execution, the operations done by the methods in the current transaction are rolled back by the database.

PROPAGATION_REQUIRES_NEW:

Change the transaction propagation type for both methods AB to PROPAGATION_REQUIRES_NEW, batchInsert() may or may not be changed

Step 1: When batchInsert() executes, create a new transaction 1 and add batchInsert() to the current transaction 1.

The second step: When batchInsert_A() is executed, the method’s transaction propagation type is PROPAGATION_REQUIRES_NEW, so it suspends transaction 1, creates a new transaction 2, and batchInsert_A() is added to transaction 2. Transaction 2 commits the transaction

Step 3: Similarly, transaction 2 will be suspended when batchInsert_B() is executed, and a new transaction 3 will be created. The batchInsert_B() is executed in transaction 3, and transaction 3 is committed. Finally, transaction 1 will be resumed, and transaction 1 will be committed when batchInsert() is executed

Since transactions are independent from each other (repeatABLE_read is the default of MySQL INNODB execution engine at high transaction isolation level), committed transactions are not rolled back in the event of a runtime exception (ongoing transactions are rolled back and unexecuted methods are not executed).

PROPAGATION_NOT_SUPPORTED:

Change the transaction propagation type of batchInsert() to PROPAGATION_REQUIRED and batchInsert_A() to batchInsert_B() to PROPAGATION_NOT_SUPPORTED

Step 1: Create a new transaction 1 and add batchInsert() to execute in transaction 1

Step 2: Because the transaction propagation type of batchInsert_A() is PROPAGATION_NOT_SUPPORTED, transactions are not supported, so when batchInsert_A() is executed, transaction 1 is suspended and executed in a non-transactional manner

Step 3: When batchInsert_B() is executed, the batchInsert_B() checks whether the transaction is currently executed or suspends the transaction. Transaction 1 is resumed after execution and the transaction is committed after batchInsert() is executed

Conclusion:

Trust to see here, you have to transaction propagation have a preliminary understanding, transaction propagation is solved in the method of nested for different methods: when do you want to run in the form of the transaction, or in the form of a new transaction to join existing transaction way, in the work we should choose according to our actual demand