This is the 29th day of my participation in the August Wenwen Challenge.More challenges in August
Understand the use of @Transactional in Spring
Transaction management is an essential part of application system development. Spring provides rich functional support for transaction management.
Declarative transactions can be made either by declaring transaction rules in a configuration file (XML) or by using the @Transactional annotation. Annotation configuration is the current popular way to use it.
The @Transactional annotation manages the implementation steps of a transaction
The implementation step for managing transactions using the @Transactional annotation is two-step.
The first step is to add transaction configuration information to the XML configuration file.
<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
Copy the code
Second, add the @Transactional annotation to the appropriate method and set the appropriate attribute information.
Attribute information for the @Transactional annotation
The property name | instructions |
---|---|
name | When you have multiple transactionmanagers in a configuration file, you can use this property to specify which TransactionManager to select. |
propagation | The propagation behavior of the transaction, which defaults to REQUIRED. |
isolation | The isolation degree of a transaction is DEFAULT. |
timeout | Timeout period for a transaction. Default value is -1. If the time limit is exceeded but the transaction has not completed, the transaction is automatically rolled back. |
read-only | Specifies whether the transaction is read-only. The default value is false. To ignore methods that do not require transactions, such as reading data, you can set read-only to true. |
rollback-for | Specifies the type of exception that can trigger transaction rollback. If more than one exception type needs to be specified, separate the exception types by commas. |
no-rollback-for | Throw the exception type specified by no-rollback-for without rolling back the transaction. |
In addition, the @Transactional annotation can be added at the class level. When the @Transactional annotation is placed at the class level, it means that all public methods of the class are configured with the same transaction attribute information.
The transaction attribute information at the method level overrides the configuration information at the class level.
The @Transactional annotation is annotated ona class:
@Transactional(propagation= Propagation.SUPPORTS,readOnly=true)
@Service(value ="employeeService")
public class EmployeeService
Copy the code
Second, notes on the use of transactions
Once you have a better understanding of Spring’s annotation-based implementation steps and the implementation mechanisms inherent in transactions, you will be better able to use annotated transaction management to avoid the problem of data not being rolled back when the system throws an exception.
1. Correctly set the propagation attribute of @Transactional
The target method is expected to conduct transaction management, but if the three propagation modes are incorrectly configured, the transaction will not be rolled back.
TransactionDefinition.PROPAGATION_SUPPORTS
: If a transaction exists, join the transaction. If there is no transaction currently, it continues in a non-transactional manner.TransactionDefinition.PROPAGATION_NOT_SUPPORTED
: Runs nontransactionally and suspends the current transaction if one exists.TransactionDefinition.PROPAGATION_NEVER
: Runs nontransactionally and throws an exception if a transaction currently exists.
2. Properly set the rollbackFor @Transactional attribute
By default, if an unchecked exception (inherited from RuntimeException) or Error is thrown in a transaction, Spring rolls back the transaction; Spring does not roll back transactions for other exceptions!
If other types of exceptions are thrown in a transaction and Spring is expected to rollback the transaction, you can specify rollbackFor. Ex. :
@Transactional(propagation= Propagation.REQUIRED, rollbackFor= MyException.class)
Copy the code
The transaction is also rolled back if the exception thrown in the target method is a subclass of the exception specified by rollbackFor.
3. @transactional only works when applied to public methods
Transaction management occurs only when the @Transactional annotation is applied to a public method.
Spring AOP checks if the target method’s decorator is public. If it is not public, the @Transactional attribute configuration information is not obtained, and as a result, the target method will not be intercepted by the TransactionInterceptor for transaction management.
4. Avoid Spring’s AOP self-invocation problem
Under Spring’s AOP proxy, target methods are managed by spring-generated proxy objects only if they are called externally, which can cause self-invocation problems.
If another method in the same class that does not have the @Transactional annotation calls the @Transactional annotation method internally, the transaction for the @Transactional annotation method is ignored and does not roll back.
@Service
public class OrderService {
private void insert(a) {
insertOrder();
}
@Transactional
public void insertOrder(a) {
//insert log info
//insertOrder
//updateAccount}}Copy the code
InsertOrder, despite the @Transactional annotation, is called by the internal insert method, the transaction is ignored, and transactions that fail are not rolled back.
2. Three major issues
The 4 fundamental elements for proper execution of database transactions are Atommicity, Consistency, Isolation and persistence.
Atomicity: all or none of the operations in the whole transaction can be completed. It is impossible to stop at some intermediate stage and complete only part of the operation.
Consistency: Refers to a transaction that can change database state. Food must always keep the system in a consistent state, no matter how many concurrent transactions there are at any given time.
Isolation: the level of isolation between two transactions.
Persistence: After a transaction completes, changes made to the database by the transaction are persisted in the database and are not rolled back.
The three major problems, from severe to mild, are as follows:
Dirty reads the question
moment | Event 1 (Husband) | Business 2 (Wife) |
---|---|---|
T1 | Query balance, display 10K | – |
T2 | – | Query balance, display 10K |
T3 | – | Online purchase 1000, display 9K |
T4 | The dinner expense is 1K, showing the balance of 8K | – |
T5 | Commit the transaction | – |
T6 | – | Roll back the transaction |
T7 | – | The final balance is 8K |
Dirty reads refer to “dirty” data read, that is, one transaction reads uncommitted data from another transaction.
Unrepeatable read problem
moment | Event 1 (Husband) | Business 2 (Wife) |
---|---|---|
T1 | Query balance, display 10K | – |
T2 | – | Query balance, display 10K |
T3 | – | Online shopping, spending 1K, balance 9K |
T4 | Dinner party, estimated cost of 2K | – |
T5 | – | Online shopping, spend 8K, balance 1K |
T6 | – | Commit the transaction |
T7 | After eating, pay the bill. The balance shows 1K, not enough to pay the bill. | – |
Unrepeatable read refers to the same data in theory, repeated read, will be different, do not have repeatability.
Phantom reads the question
moment | Event 1 (Husband) | Business 2 (Wife) |
---|---|---|
T1 | – | Query credit card consumption record, display 10 records |
T2 | Online shopping | – |
T3 | Commit the transaction | – |
T4 | – | Print consumption records. There are 11 records |
Illusory reading is similar to unrepeatable reading in that the second reading actually changes the data compared to the first reading, as if seeing an illusion.
An unrepeatable read is similar to a phantom read in that the second read is different from the first read. But they describe different priorities (and the extent of their impact).
- Unrepeatable read problem. It emphasizes that the content of a piece of data has changed between two reads. (Because of the UPDATE statement)
- The phantom problem, which emphasizes that the total amount of data in the whole data, changes between “I” and “I” reads. (Because of the INSERT/delete statement)
- The illusory problem is less harmful than the unrepeatable problem.
3. Four isolation levels
The isolation level indicates how much access “others” have to the table when “I” operates on it. The higher the isolation level of “I”, the less power others have, so that “he” can perform the actions he wants to perform without permission, and then it has to wait for “I” to complete the operation.
There are four isolation levels in the database domain (note that this is not a unique concept in Java) that address the three problems described above, one more problem for each of the four isolation levels, from solving nothing to solving everything.
Isolation level | To solve the problem | note |
---|---|---|
READ_UNCOMMITTED | Doesn’t solve anything | – |
READ_COMMITTED | Can be solvedDirty read The problem |
– |
REPEATABLE_READ | Can be solvedUnrepeatable read The problem |
Including addressDirty read The problem |
SERIALIZABLE | To solvePhantom read The problem |
Including addressUnrepeatable read andDirty read The problem |
4. Communication mechanism
Propagation behavior | meaning | note |
---|---|---|
REQUIRED | When the method is called, if there is no current transaction, the transaction is created; If something already exists, the previous transaction is used. | The default value |
SUPPORTS | When a method is invoked, transactions are not enabled if there is no current transaction; If transactions are currently enabled, the current transaction is used. | – |
MANATORY | Methods must run within a transaction. | If there is no current transaction, an exception is thrown. |
REQUIRES_NEW | The method runs in a new transaction regardless of whether the current transaction exists | Always start a new transaction and execute this method. |
NOT_SUPPORTED | No transactions are supported, no current transactions exist and no new transactions are created; If a current transaction exists, it is suspended and not resumed until the method ends | Applies to databases and SQL statements that do not support transactions |
NEVER | Transactions are not supported. | The “opposite” of MANATORY throws an exception directly if there is a current transaction. |
NESTED | Nested transactions. Advanced version of REQUIRES_NEW | Support the use of savepoints in the current transaction, you can roll back to the savepoint; If the current transaction has no savepoint, it is exactly equivalent to REQUIRES_NEW |
Needless to say, the most commonly used is REQUIRED, followed by REQUIRES_NEW. These are the most common business processes, while the others are for specific business processes.
In essence, the communication mechanism describes whether and what kind of influence will be caused by the failure of a partial behavior in an overall behavior.