SpringBoot与事务控制@Transactional(详细)

众所周知,保证数据库一致性的操作,就是事务的控制。而Spring事务管理可以分为两种:编程式(编写代码即xml配置文件)以及声明式(通过切面编程即AOP注入)(具体配置可见博客)。

对于SpringBoot,推荐操作是,使用@Transactional注解来申明事务(@Transactional注解详情可见博客)。

下面一起使用@Transactional来添加事务控制。

1、导包

要在Spring boot中支持事务,首先要导入Spring boot提供的JDBC或JPA依赖:

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-jdbc</artifactId>
   <scope>test</scope>
</dependency>
 
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-jpa</artifactId>
   <scope>test</scope>
</dependency>

当我们导入这两个包后,SpringBoot会自动默认注入DataSourceTransactionManager或JpaTransactionManager。

2、在启动类上添加@EnableTransactionManagement注解

由于SpringBoot会自动配置事务,所以这个注解可加也不加,具体实现可在org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration类中查看。

@SpringBootApplication
//启用事务管理(可省略)
@EnableTransactionManagement
@MapperScan("mapper路径")
public class KxlApplication {
    public static void main(String[] args) {
        SpringApplication.run(KxlApplication.class, args);
    }
}

三、在service层添加@Transactional注解

@Transactional注解可加在类上,也可加在方法上,@Transactional具体使用详情可见博客。

若你写代码的风格规范的话,一般@Transactional加在Service层。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@Service
@Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED)
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
public class TestService implements ITestService {
    @Autowired
    private TestMapper testMapper;

}
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS),该注解的作用是表明此类上所有方法上的事务都是CGLib方式代理的。
具体可详见博客。

以上配置本人运行未报错,但有些小伙伴在启动项目时可能会遇到类似以下报错,
Description:

The bean 'testService' could not be injected as a 'com.pk.kxl.service.impl.TestService' because it is a JDK dynamic proxy that implements:
    com.pk.kxl.service.ITestService


Action:

Consider injecting the bean as one of its interfaces or forcing the use of CGLib-based proxies by setting proxyTargetClass=true on @EnableAsync and/or @EnableCaching.

这个原因是由jdk自动代理与CGlib代理两种代理方式的区别造成的,如有发现可以完全按照我的配置,也可参考博客。

猜你喜欢

转载自www.cnblogs.com/pengpengdeyuan/p/12736799.html