专注于 JetBrains IDEA 全家桶,永久激活,教程
持续更新 PyCharm,IDEA,WebStorm,PhpStorm,DataGrip,RubyMine,CLion,AppCode 永久激活教程

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、AnnotationTransactionAttributeSource、TransactionInterceptor的类结构图。

首先要清楚几个概念:

  • ClassFilter、MethodMatcher 共同实现了「判断是否拦截方法」的能力
  • Pointcut,组合ClassFilter、MethodMatcher,用于识别是否对一个类方法进行增强
  • Advice,承载增强能力的标签类
  • Advisor,承载AOP中的advice、pointcut能力的类

104_1.png

构造流程时序

104_2.png

通过 AnnotationAwareAspectJAutoProxyCreator 进行代理对象的生成,其原理就是在进行IOC容器的初始化时,初始化bean都会回调 BeanPostProcessor.postProcessAfterInitialization 方法。也就是在这时进行代理对象的生成。

在生成过程中,会寻找 IOC 容器中的 Advisor,在启用事务控制之后,默认有 BeanFactoryTransactionAttributeSourceAdvisor ,将通过 ProxyFactory 创建代理对象:CglibAopProxy 或者 JdkDynamicAopProxy,代理对象的实现根据 spring.aop.proxy-target-class 属性和被代理类是否为接口来决定。默认情况下,使用CglibAopProxy。

切入事务管理的执行流程

104_3.png

事务回滚

104_4.png

事务提交

104_5.png

与事务管理流程相关的类:

  • 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;
}

未经允许不得转载:搜云库技术团队 » spring事务原理和事务同步器使用简介

JetBrains 全家桶,激活、破解、教程

提供 JetBrains 全家桶激活码、注册码、破解补丁下载及详细激活教程,支持 IntelliJ IDEA、PyCharm、WebStorm 等工具的永久激活。无论是破解教程,还是最新激活码,均可免费获得,帮助开发者解决常见激活问题,确保轻松破解并快速使用 JetBrains 软件。获取免费的破解补丁和激活码,快速解决激活难题,全面覆盖 2024/2025 版本!

联系我们联系我们