一、Spring Boot 事务相关问题
1、如何使用事务
2、JDBC和JPA的事务管理分别是什么?
3、指定Spring中使用使用哪种事务类型
4、项目多个事务,如何指定
5、为何在实际开发中我们在启动类上面不写@EnableTransactionManagement 事务为什么还是可以生效?
二、解答
第一个问题:
使用注解 @EnableTransactionManagement 开启事务支持后,然后在访问数据库的Service方法上添加注解 @Transactional便可
第二个问题:事务管理器
项目中数据库组件如果是spring-boot-starter-jdbc,框架会默认注入DataSourceTransactionManager
如果你添加的是spring-boot-starter-data-jpa依赖,框架会默认注入JpaTransactionManager实例。
JPA的事务管理器和JDBC的事务管理器都实现了PlatformTransactionManager接口
测试项目中使用的是什么类型的事务
//参数platformTransactionManager spring会默认帮我们住进来
@Bean
public Object testBean(PlatformTransactionManager platformTransactionManager){
System.out.println(platformTransactionManager.getClass().getName());
return new Object();
}
问题三:自定义事务类型
设置Spring的事务类型是DataSourceTransactionManager
@Bean
public PlatformTransactionManager txManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);//其中dataSource框架会自动为我们注入
}
//在Spring容器中,我们手工注解@Bean 将被优先加载,框架不会重新实例化其他的PlatformTransactionManager实现类
@Configuration
public class Profiledemo implements TransactionManagementConfigurer {
//注入事务管理器2
@Resource(name="txManager2")
private PlatformTransactionManager txManager2;
//创建事务管理器2
@Bean(name = "txManager2")
public PlatformTransactionManager txManager2(EntityManagerFactory factory) {
return new JpaTransactionManager(factory);
}
//创建事务管理器1
@Bean(name = "txManager1")
public PlatformTransactionManager txManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
//实现接口TransactionManagementConfigurer方法,其返回值代表在拥有多个事务管理器的情况下默认使用的事务管理器
@Override
public PlatformTransactionManager annotationDrivenTransactionManager() {
return txManager2;
}
}
Service使用中指定事务
public class Service{
//使用value具体指定使用哪个事务管理器
@Transactional(value="txManager1")
@Override
public void xxx() {
}
// 在存在多个事务管理器的情况下,默认使用上面annotationDrivenTransactionManager()方法返回的事务管理器
@Transactional
public void xxx() {
}
}
注意:多个数据多个事务管理器,如果没有重写annotationDrivenTransactionManager方法,并且Transactional没有指定value,启动是会报错的
问题五:
就算没有@EnableTransactionManagement,只写了@Transactional还是有效的,详细可以看下https://zhaocunwei.blog.csdn.net/article/details/105924209这个文章。
大致意思是Spring在启动的时候,回去读取配置SpringBoot默认的配置文件,配置文件就包含了默认加载事务
后面会介绍TransactionAutoConfiguration类
问题:编程式事务管理和声明式事务管理区别
1、编程式事务是在代码中调用beginTransaction()、commit()、rollback()等事务管理相关的方法。
2、声明式事务管理的实现,主要有通过 TransactionProxyFactoryBean、@Transactional、Aspectj AOP