spring-boot 事务实现原理

文章讲述了如何在SpringBoot中实现动态事务管理,主要涉及@Transaction注解的使用、SpringBoot的bean管理、AOP流程以及TransactionInterceptor的作用。通过@EnableTransactionManagement开启事务管理,并由Spring自动配置事务管理器。TransactionAutoConfiguration类在启动时加载,配置事务管理相关组件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、 如何实现动态事务

如何实现其实就是遇到问题和解决问题的过程。

  1. 如何知道这个方法需要开启事务?
    答:只要给这个方法打上一个标记,有标记的方法就被认为需要开启事务。就像别人给你一块糖,不管它是什么糖,是大的、小的、方的、还是圆的。
  2. 虽然有了标记,但是这个标记如何被处理?
    答:需要能解析这个标记的程序来处理标记,也就是开启事务。
    就像别人给了你一块糖,你要能把糖吃到嘴里。如果你不知道如何打开包装,吃不到,那这个糖就不是糖了。

综上所述,我们需要两个东西来实现,一个是标记,另一个就是解析标记的程序。可以说spring体系下实现的功能大都需要这两样东西。

二、spring-boot 实现事务需要的基础知识
  1. spring-boot 查找bean的流程
  2. spring-context 初始化流程
  3. spring-aop 流程
三、spring-boot实现流程
  1. 把需要事务的对象交个spring管理
  2. 给需要的方法打上标记,即@Transactional 注解
  3. 把解析标记的程序交给spring。这个程序并不需要我们自己写,spring已经写好了,即TransactionInterceptor对象。默认spring-boot自动实现了这个流程。
  4. 需要spring-aop。@Transactional 标记的方法作为pointcut
    ,TransactionInterceptor作为advice。默认spring-boot自动实现了这个流程。
四、spring-boot事务实现原理

实现原理,主要写上面所说的3,4两个流程。

  1. spring-boot 查找bean的流程中其中一步是读取jar文件下的spring.factories文件并加载其中的类。这里加载了org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration 类。下面是这个类部分代码。
public class TransactionAutoConfiguration {

public static class EnableTransactionManagementConfiguration {

           @Configuration(proxyBeanMethods = false)
           @EnableTransactionManagement(proxyTargetClass = true)//这个注解是事务实现的入口
           @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
 matchIfMissing = true)
           public static class CglibAutoProxyConfiguration {
           }
     }
}

  1. @EnableTransactionManagement 加载了两个对象
  • org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration :将@Transactional标记包装成切点,TransactionInterceptor包装advice,创建了实现Advisor(aop 使用该接口)接口的对象
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {

    //该bean实现了Advisor接口,aop会查找该接口的对象,并实现调用代理transactionInterceptor中的开启事务方法
	@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor(
			TransactionAttributeSource transactionAttributeSource,
			TransactionInterceptor transactionInterceptor) {
		BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
		advisor.setTransactionAttributeSource(transactionAttributeSource);
		advisor.setAdvice(transactionInterceptor);
		if (this.enableTx != null) {
			advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
		}
		return advisor;
	}

   //代表@Transactional 注解的对象
	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public TransactionAttributeSource transactionAttributeSource() {
		return new AnnotationTransactionAttributeSource();
	}

	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public TransactionInterceptor transactionInterceptor(
			TransactionAttributeSource transactionAttributeSource) {
		TransactionInterceptor interceptor = new TransactionInterceptor();
		interceptor.setTransactionAttributeSource(transactionAttributeSource);
		if (this.txManager != null) {
			interceptor.setTransactionManager(this.txManager);
		}
		return interceptor;
	}

}
  • org.springframework.context.annotation.AutoProxyRegistrar :开启aop能力;向spring注入了org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator 对象,该对象会拦截其他对象的创建并生成代理对象;AnnotationAwareAspectJAutoProxyCreator 实现了BeanPostProcessor,在spring-context加载bean的流程中会调用如下方法(AnnotationAwareAspectJAutoProxyCreator祖先类中定义)

@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
               if (bean != null) {
                Object cacheKey = getCacheKey(bean.getClass(), beanName);
                if (this.earlyProxyReferences.remove(cacheKey) != bean) {
                     // 这里会查找所有实现Advisor接口的对象,并生成代理对象
                     return wrapIfNecessary(bean, beanName, cacheKey);
                }
           }
           return bean;
}

五、图示

请添加图片描述

<think>好的,我现在需要回答用户关于Spring Boot事务管理器自动注入的问题。首先,我需要回忆一下Spring Boot事务管理机制。根据引用[2]中的信息,Spring Boot通过自动配置简化了事务管理,通常会自动配置一个PlatformTransactionManager的实现,比如DataSourceTransactionManager。 用户的问题是关于自动注入的配置和示例,所以我需要解释如何通过自动配置实现,以及可能需要的手动配置情况。记得要提到@EnableTransactionManagement注解,不过实际上Spring Boot已经默认启用了,所以可能不需要显式添加。 接下来,我需要考虑不同的数据访问技术,比如JPA或JDBC,对应的TransactionManager不同,比如JpaTransactionManager和DataSourceTransactionManager。Spring Boot会根据classpath中的依赖自动选择正确的实现,这部分需要说明清楚。 然后,用户可能需要一个配置示例。这时候要提供一个简单的代码示例,展示如何定义DataSource,并且通过@Bean方法配置PlatformTransactionManager。不过根据自动配置的原理,大多数情况下不需要手动配置,但如果有多个数据源,就需要自己定义。 还需要提到@Transactional注解的使用,以及如何通过properties文件进行配置,比如spring.transaction.default-timeout。这部分可以引用引用[2]和[3]的内容,说明事务管理的方式。 最后,生成相关问题的时候,要考虑用户可能进一步的问题,比如多数据源配置、隔离级别设置、混合编程式和声明式事务等。这些都需要基于已有的引用材料来构思,确保问题相关且有依据。 现在需要组织语言,确保结构清晰,步骤明确,同时正确引用给出的参考文献。注意使用中文,避免使用Markdown格式,数学公式用$...$,独立公式用$$...$$,但在这个问题中可能用不上数学公式。同时检查LaTeX语法是否正确,虽然这个问题可能更多是代码和配置示例。 总结步骤: 1. 自动配置机制,默认的TransactionManager。 2. 示例代码展示自动注入的情况。 3. 手动配置的场景和示例。 4. 配置属性说明。 5. 引用相关文献,比如[^2]和[^3]。 现在把这些点整合成连贯的回答,并生成相关问题。</think>### Spring Boot事务管理器自动注入配置详解 在Spring Boot中,事务管理器的自动注入主要通过以下机制实现: #### 1. 自动配置机制 Spring Boot根据项目依赖**自动选择事务管理器实现**。例如: - 使用JDBC时默认注入$DataSourceTransactionManager$ - 使用JPA时默认注入$JpaTransactionManager$ 触发条件:存在`DataSource` bean且未显式定义`PlatformTransactionManager`[^2] #### 2. 典型配置示例 ```java // 自动配置的数据源 @Bean public DataSource dataSource() { return DataSourceBuilder.create().build(); } // 自动创建的事务管理器(无需显式声明) @Transactional public void serviceMethod() { // 数据库操作 } ``` #### 3. 手动配置场景 当存在多个数据源时需要显式声明: ```java @Configuration public class TransactionConfig { @Bean @Primary public PlatformTransactionManager transactionManager(DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } @Bean public PlatformTransactionManager secondTxManager(DataSource secondDataSource) { return new DataSourceTransactionManager(secondDataSource); } } ``` #### 4. 关键配置属性 ```properties # 配置事务默认超时时间 spring.transaction.default-timeout=30 # 开启事务日志 logging.level.org.springframework.jdbc.datasource.DataSourceTransactionManager=DEBUG ``` #### 5. 编程式事务管理 结合自动注入的事务管理器: ```java @Autowired private PlatformTransactionManager transactionManager; public void manualTransaction() { TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition()); try { // 业务操作 transactionManager.commit(status); } catch (Exception e) { transactionManager.rollback(status); } } ``` [^3]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值