Spring (IV) -- transaction propagation (introduction, example explanation, level introduction, code implementation)
1, Transaction propagation
1. Transactional communication introduction
Spring defines an enumeration class to facilitate the use of transaction propagation behavior:
2. Transaction propagation example explanation
Or use the classic transfer example:
In the past, each database logic was written in the dao layer, and then the service layer called the two methods of the dao layer to complete the logic of one party reducing money and the other adding money. The transaction is to wrap the two logic.
Don't use this method now; Call the method of adding money in the logic of reducing money. In this way, you only need to call the logic of reducing money, and you will naturally use the logic of adding money. A set of methods is the logic of transfer.
At this time, the propagation of transactions is used. There are transactions on the outer layer. If they are rolled back, whether they are rolled back or not; Similarly, if the inner layer rolls back, will the outer layer roll back?
3. Introduction to transaction propagation level
Transaction propagation is hierarchical. Different levels have different effects. Mainly understand the first three, and the last four are less used:
a,REQUIRED
First, start the transaction at ordinary times. The default level is REQUIRED.
Secondly, the internal method modified by this level will newly open its own transaction, and the opened transactions are independent of each other and do not interfere with each other: that is, if the external method does not open the transaction, the internal method will open the transaction itself (because the default is the REQUIRED level).
Finally, if both inside and outside are at this level, as long as one of them is rolled back (outer rollback or inner rollback), the whole transaction will be rolled back. If one of the internal and external triggers an exception, both the internal and external are rolled back.
b,REQUIRES_NEW
The internal method of this level modification will newly open its own transactions, and the opened transactions are independent of each other and do not interfere with each other. Because it is not at this level by default, it means that if the outer method starts a transaction, two transactions exist at the same time.
At this time, there are two situations: internal and external rollback, internal rollback and external rollback.
Let's start with the first case: if the inner layer method triggers an exception, it should be rolled back. If the inner layer exception is not handled, the exception will be thrown to the outer layer. At this time, the outer layer will also receive an exception, so the outer layer will also roll back if it triggers an exception. This is the rollback of both inner and outer layers.
The second case is that the inner layer triggers an exception, but handles the exception, so the outer layer cannot receive the exception. At this time, only the inner layer rolls back, but the outer layer will not roll back.
So how to deal with exceptions? In fact, try... catch handles exceptions:
c,NESTED
When the external transaction is not opened, the function of this level is the same as the default level. The opened transactions are independent of each other and do not interfere with each other.
If an external transaction is enabled, the internal method modified by NESTED is a sub transaction of an external transaction. If the external transaction is rolled back, the internal transaction will also be rolled back; Internal transactions are rolled back, but external transactions are not rolled back.
d,
h. Attention
If the operation field has no index, the table lock will be triggered. That is, when you perform a database operation, the whole table will be locked. At this time, other operations cannot operate on this table. The row lock is triggered only when the operated field is an index; Only then can other rows of the table be operated.
For example, the primary key ID has an index. For example, username may not have an index and needs to be set by itself. So innodb doesn't have a table lock. It depends.
4. Code implementation
Import dependency first:
<properties> <slf4j.version>1.7.32</slf4j.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.3.14</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.3.14</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.9.7</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.7</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.8</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.27</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>${slf4j.version}</version> <scope>runtime</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>${slf4j.version}</version> <scope>runtime</scope> </dependency> <dependency> <groupId>com.googlecode.usc</groupId> <artifactId>jdbcdslog</artifactId> <version>1.0.6.2</version> </dependency> </dependencies>