大家好,我是考100分的小小码 ,祝大家学习进步,加薪顺利呀。今天说一说spring事务原理和事务同步器使用简介,希望您对编程的造诣更进一步.
如何启用事务支持
引入依赖
<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 生效。其实现又将引入以下配置
- AutoProxyRegistrar:ImportBeanDefinitionRegistrar 实现类,容器启动时回调其registerBeanDefinitions方法,以便引入更细化的配置
- InfrastructureAdvisorAutoProxyCreator 由于优先级比 AnnotationAwareAspectJAutoProxyCreator 低,因此并未生效
- ProxyTransactionManagementConfiguration @Configuration标记的配置类
- BeanFactoryTransactionAttributeSourceAdvisor
- 内部的pointvut属性为:TransactionAttributeSourcePointcut
- AnnotationTransactionAttributeSource 读取@Transactional属性值,暴露给 spring 事务框架
- TransactionInterceptor
- TransactionalEventListenerFactory
- BeanFactoryTransactionAttributeSourceAdvisor
如何构造出带事务的代理类
BeanFactoryTransactionAttributeSourceAdvisor、AnnotationTransactionAttributeSource、TransactionInterceptor的类结构图。
首先要清楚几个概念:
- ClassFilter、MethodMatcher 共同实现了「判断是否拦截方法」的能力
- Pointcut,组合ClassFilter、MethodMatcher,用于识别是否对一个类方法进行增强
- Advice,承载增强能力的标签类
- Advisor,承载AOP中的advice、pointcut能力的类
构造流程时序
通过 AnnotationAwareAspectJAutoProxyCreator 进行代理对象的生成,其原理就是在进行IOC容器的初始化时,初始化bean都会回调 BeanPostProcessor.postProcessAfterInitialization 方法。也就是在这时进行代理对象的生成。
在生成过程中,会寻找 IOC 容器中的 Advisor,在启用事务控制之后,默认有 BeanFactoryTransactionAttributeSourceAdvisor ,将通过 ProxyFactory 创建代理对象:CglibAopProxy 或者 JdkDynamicAopProxy,代理对象的实现根据 spring.aop.proxy-target-class 属性和被代理类是否为接口来决定。默认情况下,使用CglibAopProxy。
切入事务管理的执行流程
事务回滚
事务提交
与事务管理流程相关的类:
- TransactionAttribute – DelegatingTransactionAttribute
- PlatformTransactionManager – DataSourceTransactionManager
- TransactionStatus
- TransactionInfo
- ConnectionHolder
在整个事务管理的流程中,主要通过 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;
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/13283.html