<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
复制代码
加入依赖之后,自动化配置类将自动配置启用事务的类对象
@Configuration
// 引入 spring-boot-starter-jdbc 之后,类路径才存在 PlatformTransactionManager,配置生效
@ConditionalOnClass(PlatformTransactionManager.class)
@AutoConfigureAfter({ JtaAutoConfiguration.class, HibernateJpaAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class, Neo4jDataAutoConfiguration.class })
@EnableConfigurationProperties(TransactionProperties.class)
public class TransactionAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public TransactionManagerCustomizers platformTransactionManagerCustomizers(
ObjectProvider<PlatformTransactionManagerCustomizer<?>> customizers) {
return new TransactionManagerCustomizers(customizers.orderedStream().collect(Collectors.toList()));
}
@Configuration
@ConditionalOnSingleCandidate(PlatformTransactionManager.class)
public static class TransactionTemplateConfiguration {
private final PlatformTransactionManager transactionManager;
public TransactionTemplateConfiguration(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
@Bean
@ConditionalOnMissingBean(TransactionOperations.class)
public TransactionTemplate transactionTemplate() {
return new TransactionTemplate(this.transactionManager);
}
}
@Configuration
@ConditionalOnBean(PlatformTransactionManager.class)
@ConditionalOnMissingBean(AbstractTransactionManagementConfiguration.class)
public static class EnableTransactionManagementConfiguration {
// 启用事务
@Configuration
@EnableTransactionManagement(proxyTargetClass = false)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false",
matchIfMissing = false)
public static class JdkDynamicAutoProxyConfiguration {
}
// 启用事务。没有配置 spring.aop.proxy-target-class 时,默认使用的 proxyTargetClass = true。使用CGLIB来生成代理
@Configuration
@EnableTransactionManagement(proxyTargetClass = true)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
matchIfMissing = true)
public static class CglibAutoProxyConfiguration {
}
}
}
复制代码
当引入依赖后,自动化配置类 TransactionAutoConfiguration 生效。其实现又将引入以下配置
BeanFactoryTransactionAttributeSourceAdvisor、AnnotationTransactionAttributeSource、TransactionInterceptor的类结构图。
首先要清楚几个概念:
通过 AnnotationAwareAspectJAutoProxyCreator 进行代理对象的生成,其原理就是在进行IOC容器的初始化时,初始化bean都会回调 BeanPostProcessor.postProcessAfterInitialization 方法。也就是在这时进行代理对象的生成。
在生成过程中,会寻找 IOC 容器中的 Advisor,在启用事务控制之后,默认有 BeanFactoryTransactionAttributeSourceAdvisor ,将通过 ProxyFactory 创建代理对象:CglibAopProxy 或者 JdkDynamicAopProxy,代理对象的实现根据 spring.aop.proxy-target-class 属性和被代理类是否为接口来决定。默认情况下,使用CglibAopProxy。
与事务管理流程相关的类:
在整个事务管理的流程中,主要通过 TransactionInterceptor 根据异常与否来切入提交、回滚的功能。由DataSourceTransactionManager封装提交、回滚两个操作的门面接口供TransactionInterceptor调用,在 DataSourceTransactionManager 内部,其内部封装了 TransactionStatus,而TransactionStatus 包含着的TransactionObject可以通过其 ConnectionHolder 来获取当前所用连接对象,进而执行提交或回滚;
除此之外,spring 还提供了 TransactionSynchronization 作为事务同步器,在「提交前、回滚前、提交后、回滚后、执行回滚(或提交)完成 」这几个时机进行同步器的回调。
用法如下
@Transactional(rollbackFor = Exception.class)
@Override
public Author save(Author author) {
jdbcTemplate.update("insert into author(name) values (?)", author.getName());
// 注册事务同步器,在事务提交后进行回调
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
@Override
public void afterCommit() {
System.out.println("after commit...");
}
});
return author;
}
复制代码