- Hello, everyone, here is the public number: Java Xiaojie to refueling
- We all know that Spring has seven kinds of transaction propagation behaviors, and they are often asked in interviews, but they all look too similar to each other, so today we will use this article to thoroughly understand them!
- There are a lot of code argumentation in the article, it is recommended to collect in the computer end to eat
- Don't say much. Just drive
Spring's seven transaction propagation behaviors
The following transaction propagation attributes are transaction annotations typed on method B
Propagation.REQUIRED: Default transaction Propagation behavior of spring, where method A calls method B. If A has A transaction, then method B is added to the transaction in method A. Otherwise, method B opens A new transaction itself
Propagation.SUPPORTS: method A calls method b. If method A has A transaction, then method B is added to the transaction in method A. Otherwise, method B executes in A non-transactional manner
Propagation.MANDATORY: Method A must call method b. If A has no transaction, method B will throw an exception
Propagation.REQUIRES_NEW: Method A calls method B. If A has transactions, then method B suspends the transactions of method A and method B restarts A new transaction itself
Propaganda. NOT_SUPPORTED: method A calls method B. If A has A transaction, then B suspends the transaction in method A. Otherwise, method B executes in A non-transactional way
Propagation.NEVER: No transaction is supported. Method A calls method B. If A has transaction, method B will throw an exception
Propagandized: Same propagandized.REQUIRED, but this propagandized property can also save a state node, preventing all NESTED transactions from being rolled back
Now that we've looked at some of the explanations for each propagation attribute, with the rest of the explanation in mind, let's look at the actual code
In actual combat
- Spring's default transaction propagation property, method A calls method B. If method A has A transaction, then method B joins the transaction in method A, otherwise method B starts A new transaction itself
Let's look at interface B
So if I write my code like this, what data is going to end up in this database?
Content of original database
Postman, let's have a look
You can see the result of the console is that they share one transaction (sqlSession is the same)
In this case, the content of the database does not change, indicating that both interfaces A and B are rolled back
A common interview question arises at this point: If an exception thrown by method B is caught by method A try catch, will the operation of method A be rolled back?
The answer is: it does
Looking at the test code, we added code to method A to catch the exception thrown by method B
One more postman, and the console outputs the following test results
When we look at the database, the data hasn't changed
Then again, if A does not catch and method B catches the exception itself, will the transaction be rolled back?
The answer is: no
Change the code of interface B
Also remove the catch exception for method A
The result at this point is
The data in the database is
Interface A and interface B are in effect and are operating on the database
What's the difference between method A and method B?
- The difference is, if method A catches an exception,Method B's transaction annotations are aware of the exception and roll back;
- And method B captured by itself,The transaction annotation of method B will not be aware of the exception and will not be rolled back
Once you understand the above example, it is easy to analyze whether the various exception/propagation properties are rolled back or not.
- Method A calls method B. If method A has A transaction, then method B is added to the transaction in method A. Otherwise, method B executes itself in A non-transactional manner
We change the transaction Propagation attribute of interface B to Propagation.SUPPORTS
A method of
The test results were
The database value hasn't changed either, so both operations are rolled back so let's take A look at this after we remove the transaction annotation for method A
The test results are yes
The database value is
Thus, neither operation is rolled back, and method B is a non-transactional operation
Method A calls method B. If method A has no transaction, then method B will throw an exception
B Interfaces are as follows:
The value of the database has not changed, so it can be seen that the transaction annotation of method B isPropagation.MANDATORYWhen method A has no transaction, an error is reported.
- Method A calls method B. If method A has A transaction, method B suspends method A's transaction and method B restarts A new transaction itself
A method of
As a result,Two interfaces can be foundDefaultSqlSessionIf interface A has A transaction, interface B suspends it and restarts A new transaction
- If A does not catch an exception, then both A and B methods are rolled back
- Method A catches an exception, then method A does not roll back
Again, if an exception is caught inside a method, then the transaction annotations on the method are not aware of the exception and the operation on the method is not rolled back!
Method A calls method B. If method A has A transaction, then method B suspends the transaction in method A, otherwise method B executes itself in A non-transactional manner
The test results were
The result of the database is
We can see that interface B takes effect and does insert A piece of data, but interface A does not take effect and does not change data. This is because an exception is thrown in interface B. Since the transaction Propagation behavior of interface B is propagandis. NOT_SUPPORTED, the transaction of interface A will be suspended. Interface B operates in A non-transactional manner (so the error is not rolled back). If the exception is found in interface A, it will be rolled back, so the data will not be changed
- Method A calls method B. If A has A transaction, then method B will throw an exception
As a result,
The database has not been changed, so it can be seen that when interface A calls interface B when there is A transaction, an error is directly reported
- REQUIRED, but this Propagation property can also save a state node to avoid all nested transactions being rolled back
As a result,
The database changes are as follows
The operation on interface A is not rolled back, but the operation on interface B is rolled back because of the "savePoint" safety point. During the operation on interface B, the current state (the operation on interface A has finished) is saved to the safety point. If interface B fails, the rollback will only be rolled back to this safety point
Note: You need to try catch the exception of interface B in interface A
Here is the public number: Java Xiaojie to refueling, we will see next time
- How is the network connected from the four-layer model
- Wanted to talk to you about memory management for the operating system
- Define a Java annotation of your own
- Five thousand words. Yes, we have an HTTP.
- The interviewer from JD.com asked me, "What about MySql,MVCC?"