Example of @transactional internal call 🌰
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 A{
public void action(a){
dosome();
}
@Transactional
public void dosome(a){
doa.insert(newObject()); }}Copy the code
As shown above, when an exception is thrown in method dosome(), the data operation is not rolled back
The solution
Idea: Force the use of AspectJ for method profiling
Springboot introduces AspectJ facets
Add AspectJ to POM.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<! -- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.5</version>
</dependency>
Copy the code
Add @enableAspectJAutoProxy to the startup class (exposeProxy = true)
@SpringBootApplication
@EnableAspectJAutoProxy(exposeProxy = true)
public class DonngPartsApplication {
public static void main(String[] args) { SpringApplication.run(DonngPartsApplication.class, args); }}Copy the code
Note: exposeProxy = true if not added, will report:
java.lang.IllegalStateException:
Cannot find current proxy: Set ‘exposeProxy’ property on Advised to ‘true’ to make it available,
and ensure that AopContext.currentProxy() is invoked in the same thread as the AOP invocation context.
(A) aopContext.currentProxy ().dosome()
Change to the following code and the transaction takes effect
@Service
public class A{
public void action(a){
((A) AopContext.currentProxy()).dosome();
}
@Transactional
public void dosome(a){
doa.insert(newObject()); }}Copy the code
@ Transactional advanced
1. Attribute information for the @Transactional annotation
attribute | describe |
---|---|
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 |
2. Propagation
- REQUIRED: Join a transaction if one exists, create a new one if not (default)
- NOT_SUPPORTED: The container does not enable transactions for this method
- REQUIRES_NEW: A new transaction is created regardless of whether a transaction exists, the old one is suspended, the new one is executed, and the old one continues
- MANDATORY: Must be executed in an existing transaction, or an exception is thrown
- NEVER: must be executed in a transaction that does not exist, otherwise an exception is thrown (as opposed to MANDATORY)
- SUPPORTS: Transactions are used if other beans call this method and declare transactions in other beans. If the other bean does not declare a transaction, then no transaction is required.
- NESTED: If a transaction currently exists, it is executed within a NESTED transaction. If there are no transactions currently, an operation similar to PROPAGATION_REQUIRED is performed.
3. Transaction timeout setting
Transactional(timeout=30) // The default is 30 seconds
4. Transaction isolation level Isolation
- READ_UNCOMMITTED: Reads uncommitted data (dirty reads and unrepeatable reads occur)
- READ_COMMITTED: Reads committed data (unrepeatable reads and phantom reads occur)
- REPEATABLE_READ: repeatable reading (phantom reading can occur)
- SERIALIZABLE: serialization
Pay attention to
Transactional can only be applied to public methods
The mere presence of the @Transactional annotation does not enable Transactional behavior; it is simply metadata
Call it a day!!!!!!
For more interesting and interesting content, welcome to my blog to communicate and improve WaterMin together