Spring源码之事务

在Spring框架中,事务管理是一个重要的功能,它可以确保在数据库操作过程中的一致性和完整性。Spring提供了多种方式来实现事务管理,其中基于注解的方式是一种简洁而方便的选择。本文将深入探讨Spring源码中基于注解的事务管理的实现原理。

Srping事务使用

事务是一组操作的集合,这些操作要么全部成功执行,要么全部回滚到初始状态。事务管理是指在应用程序中对数据库操作进行管理,确保事务的一致性和隔离性。
下面我们来看一段Spring事务在我们平时开发中的应用

// 开启Spring事务,通过注解@EnableTransactionManagement
@Configuration
@ComponentScan(basePackages = {"com.gu"})
@EnableTransactionManagement 
public class MainConfig {
...
}

// 在具体类或方法上添加注解@Transactional
@Service
public class ReimburseService {
    
    @Autowired
    private ExpenseServiceRepository expenseServiceRepository;
    
	@Transactional
	public void function1(Reimburse reimburse){
		 // 保存报销单
        reimburseRepository.save(reimburse);
        // 保存费用
        expenseServiceRepository.save(reimburse.getExpense());
	}
}

@Service
public class ExpenseService {
    
	@Transactional
	public void function2(Expense expense){
		 // 保存费用
        expenseServiceRepository.save(expense);
	}
}

上述例子主要关注两个注解@Transactional和@EnableTransactionManagement

  • @EnableTransactionManagement
    用于启用Spring的事务管理功能。通常在配置类上使用
  • @Transactional
    用于标记需要进行事务管理的方法或类。可以在方法上或类上使用,表示该方法或类需要在事务中执行

Spring事务准备

@EnableTransactionManagement

在这里插入图片描述

现在来看注解@EnableTransactionManagement ,可以看到该注解实际上就是会自动注册TransactionManagementConfigurationSelector作为配置类的一个组件.

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
...
}

接着来看TransactionManagementConfigurationSelector

// 实际就是在spring容器里增加了两个bean
// AutoProxyRegistrar 和 ProxyTransactionManagementConfiguration
@Override
protected String[] selectImports(AdviceMode adviceMode) {
	switch (adviceMode) {
		case PROXY:
			return new String[] {AutoProxyRegistrar.class.getName(),
						ProxyTransactionManagementConfiguration.class.getName()};
		case ASPECTJ:
			return new String[] {determineTransactionAspectClass()};
		default:
			return null;
	}
}

AutoProxyRegistrar

AutoProxyRegistrar的主要作用是开启AOP.
向Spring容器中注册了一个 InfrastructureAdvisorAutoProxyCreator的Bean. 而InfrastructureAdvisorAutoProxyCreator 继承了AbstractAdvisorAutoProxyCreator,所以这个类的主要作用就是开启自动代理的作用,也就是一个BeanPostProcessor,会在初始化后步骤中去寻找Advisor类型的Bean,并判断当前某个 Bean是否有匹配的Advisor,是否需要利用动态代理产生一个代理对象。

// 向Spring容器中注册了一个 InfrastructureAdvisorAutoProxyCreator
AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
// ->
return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);

ProxyTransactionManagementConfiguration

是一个配置类,里面定义了3个Bean

@Configuration(proxyBeanMethods = false)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
	
	/**
	 * 创建一个事务切面(就是一个BeanPostProcess)
	 * 一个advisor,需要TransactionAttributeSource + TransactionInterceptor构造
	 * @param transactionAttributeSource
	 * @param transactionInterceptor
	 * @return
	 */
	@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor(
			TransactionAttributeSource transactionAttributeSource, TransactionInterceptor transactionInterceptor) {
		// 创建BeanFactoryTransactionAttributeSourceAdvisor对象作为事务切面
		BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
		// 设置事务属性源
		advisor.setTransactionAttributeSource(transactionAttributeSource);
		// 设置事务拦截器
		advisor.setAdvice(transactionInterceptor);
		// 设置切面的顺序
		if (this.enableTx != null) {
			advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
		}

		return advisor;
	}
	
	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public TransactionAttributeSource transactionAttributeSource() {
		// 是个工具类,相当于pointcut,用来判断@Transactional
		return new AnnotationTransactionAttributeSource();
	}

	/**
	 * 创建一个事务拦截器
	 * 相当于advice,是代理逻辑,当某个类中存在@Transactional注解时,到时就产生一个代理对象作为Bean,
	 * 代理对象在执行某个方法时,最终就会进入到TransactionInterceptor的 invoke()方法。
	 * @param transactionAttributeSource
	 * @return
	 */
	@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;
	}

}

Sprin事务流程

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值