Attribute information in @Transaction
value :
This property can be used to specify which transaction manager to select when you have multiple transaction managers in a configuration file.
propagation :
Propagation behavior of transactions. The so-called transaction propagation behavior refers to the situation that A transaction context exists before the current transaction is opened (for example, we add transaction to method A and method B respectively, and then call B in A, then we need to select the transaction propagation behavior, so that A makes the expected response.
This property contains the following options:
- REQUIRED (default) :
- If A transaction exists in the context when method A is called, join the current transaction
- If method A is called without A transaction in the context, A new transaction is created
- When method A calls method B from method A, methods A and B use the same transaction
- If method B fails and needs to be rolled back, the entire transaction is rolled back
- REQUIRED_NEW:
- For methods A and B, A new transaction is started whether or not A transaction exists when the method is called
- And if a transaction exists when the method is called, the current transaction is deferred
- An exception to method B will not cause A rollback of method A
- NESTED:
- Similar to REQUIRED_NEW, but JDBC support, not JPA or Hibernate support
- SUPPORTS:
- If a transaction is already started in the context when the method is called, this transaction is used
- If there is no transaction in the context when the method is called, transactions are not used
- NOT_SUPPORTS:
- Run in a non-transactional manner, and if there is a transaction, it will be suspended from the method call to the end
- NEVER:
- Runs in a non-transactional manner, throwing an exception if a transaction exists
- MANDATORY:
- Force methods to execute in a transaction and join the current transaction if one exists
- If no transaction exists, an exception is thrown
Isolation:
The isolation level of the transaction. The isolation level of a transaction refers to the isolation degree of several concurrent transactions, which are read uncommited, read Commited, read REPEATable, serializable. The four levels solve the problems of dirty reads, unrepeatable reads, and phantom reads one by one.
This property contains the following options:
- READ_UNCOMMITED:
- The lowest transaction isolation level, which allows another transaction to see the uncommitted data of that transaction; Can result in dirty reads, unrepeatable reads, and phantom reads
- READ_COMMITED:
- Ensure that a transaction is committed before another transaction can read it; Prevents dirty reads, but may result in unrepeatable and phantom reads
- REPEATABLE_READ:
- It can not only implement READ_COMMITED function, but also carry out the following restrictions: when A transaction reads A piece of data, B transaction will not be allowed to modify the record; Prevents dirty and unrepeatable reads, but may cause phantom reads
- The SERIALIZABLE.
- The most expensive but reliable transaction isolation level, where transactions are processed and executed sequentially; In addition to preventing dirty and unrepeatable reads, it also avoids phantom reads
- DEFUALT:
- Use the default isolation level of the current database, such as READ_COMMITED for Oracle and SqlServer and REPEATABLE_READF for MySQL
The concepts of dirty read, unrepeatable read and phantom read are as follows:
- Dirty read: Uncommitted data is read
- For example, operation A tries to modify the account balance from 2000 to 1000, and operation B tries to increase the account balance by 1000 after reading the modification. During the execution of operation B, an error occurred in operation A, resulting in A rollback, and the account balance changed back to 2000. So, after B commits the operation, the account balance should be 2000+1000=3000, but because B read the wrong data, namely dirty data, the account balance is only 1000+1000=2000.
- Non-repeatable read: Data is read repeatedly and inconsistent
- For example, we have an operation A that needs to read the balance of the account several times. In the first read of A, the balance is 1000, and then the other operation B changes the balance to 2000. Then in the second read of A, the balance is changed to 2000, which is different from the first read. The system cannot read the same data in the same operation. This is called unrepeatable read.
- Phantom read: multiple reads with inconsistent data amount
- For example, when transaction A performs A read operation, it needs to count the total amount of data for several times. After the previous query of the total amount of data, transaction B performs the operation of adding new data and submits it. When transaction A reads again, it will read several more pieces of data just like an illusion, so it is called phantom read.
Timeout:
The expiration time of the transaction. Default is the transaction expiration time for the current database
Readonly:
Specifies whether the current transaction is read-only. The default is false
RollbackFor:
Specifies which or which exceptions need to be rolled back when a transaction occurs. Default is a subclass of Throwable
NoRollBackFor:
Specify which or which exceptions do not cause the transaction to roll back when they occur
Annotated transaction implementation mechanism in Spring
When applying a system call to a target method that declares @Transactional, the Spring Framework:
- AOP proxies are used by default
- Generate a proxy object while the code is running
Based on the @Transaction attribute configuration information, this proxy object will:
- Determines whether the target method is intercepted by the TransactionInterceptor
When a TransactionInterceptor intercepts, it:
- The transaction is first created and joined before the target method begins execution
- The target method is then executed
- According to the execution is abnormal, the use of abstract transaction manager AbstarctPlatformTransactionManager operation data source DataSource to commit or rollback transaction.
Other Matters needing attention
@Transaction is valid only when applied to a public method
This is because when using Spring AOP proxies, Spring intercepts methods before calling the TransactionInterceptor interceptor. CglibAopProxy intercept method of an inner class can indirectly invoked AbstractFallbackTransactionAttributeSource (Spring get @ the Transaction through this class Annotations computeTransactionAttribute method of transaction attribute configuration attribute information).
This method checks if the target method’s modifier is public. If it isn’t, it doesn’t get the @Transaction property configuration information, and as a result, it doesn’t use the TransactionInterceptor to intercept the target method, thus preventing Transaction management.
Avoid AOP self-invocation problems in Spring
Under Spring’s AOP proxy, the target method can only be managed by a spring-generated proxy object if the target method is invoked externally. If another method in the same class without the @Transaction annotation calls the @Transaction annotated method, the Transaction of the @Transaction annotated method will be ignored and no rollback will occur.
For example, we have A Demo class that has two methods A and B. When A declares A transaction and B does not, when B calls A, the transaction in A will not take effect.
@Server
public class Demo {
public void methodB(a) {
methodA();
}
@Transaction
public void methodA(a) {
// ...}}Copy the code
This is because, when intercepting with AOP, we first create a proxy class for Demo, at which point we have two Demo objects in our system: the target Demo object and the generated proxy Demo object. AOP interception is valid if the proxy class’s B method is called from the proxy class’s A method, but not if the target class’s B method is called from the proxy class’s A method.