众所周知,保证数据库一致性的操作,就是事务的控制。而Spring事务管理可以分为两种:编程式(编写代码即xml配置文件)以及声明式(通过切面编程即AOP注入)(具体配置可见博客)。
对于SpringBoot,推荐操作是,使用@Transactional注解来申明事务(@Transactional注解详情可见博客https://www.cnblogs.com/pengpengdeyuan/p/12737891.html)。
下面一起使用@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加在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方式代理的。
具体可详见博客https://www.cnblogs.com/pengpengdeyuan/p/12737585.html。
以上配置本人运行未报错,但有些小伙伴在启动项目时可能会遇到类似以下报错,
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代理两种代理方式的区别造成的,如有发现可以完全按照我的配置,也可参考博客https://www.cnblogs.com/pengpengdeyuan/p/12737585.html。