<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; } 复制代码