springboot事务处理流程

从@EnableTransactionManagement这个注解开始

一般想要了解springboot中某个功能的实现,可以考虑从@EnableXXX注解开始;
@EnableXXX注解一般是配合@Import使用,导入一个配置类或ImportSelector,ImportBeanDefinitionRegistrar实现类;

查看@EnableTransactionManagement注解

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


	boolean proxyTargetClass() default false;

	AdviceMode mode() default AdviceMode.PROXY;

	int order() default Ordered.LOWEST_PRECEDENCE;

}

发现导入了TransactionManagementConfigurationSelector这个类;
这个类是ImportSelector的实现类,会将selectImports方法的返回值注册到容器中;
这里注册了两个类:

  1. AutoProxyRegistrar
  2. ProxyTransactionManagementConfiguration
public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {

	/**
	 * Returns {@link ProxyTransactionManagementConfiguration} or
	 * {@code AspectJ(Jta)TransactionManagementConfiguration} for {@code PROXY}
	 * and {@code ASPECTJ} values of {@link EnableTransactionManagement#mode()},
	 * respectively.
	 */
	@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;
		}
	}

	private String determineTransactionAspectClass() {
		return (ClassUtils.isPresent("javax.transaction.Transactional", getClass().getClassLoader()) ?
				TransactionManagementConfigUtils.JTA_TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME :
				TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME);
	}

}

AutoProxyRegistrar的作用

AutoProxyRegistrar是ImportBeanDefinitionRegistrar的实现类,会在registerBeanDefinitions方法中注册Bean定义

public class AutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

	private final Log logger = LogFactory.getLog(getClass());

	/**
	* 	importingClassMetadata为注解所在类的元信息,可以获取完整类名,以及其上的注解
	*   这里就是为了获取@EnableTransactionManagement 注解的相关信息
	*/
	@Override
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		boolean candidateFound = false;
		// 获取类上所有的注解
		Set<String> annTypes = importingClassMetadata.getAnnotationTypes();
		// 遍历这些注解,尝试找到包含mode和proxyTargetClass属性的注解,即@EnableTransactionManagement 
		for (String annType : annTypes) {
			AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annType);
			if (candidate == null) {
				continue;
			}
			Object mode = candidate.get("mode");
			Object proxyTargetClass = candidate.get("proxyTargetClass");
			if (mode != null && proxyTargetClass != null && AdviceMode.class == mode.getClass() &&
					Boolean.class == proxyTargetClass.getClass()) {
				candidateFound = true;
				// 默认就是PROXY,会走这个if
				if (mode == AdviceMode.PROXY) {
					AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
					if ((Boolean) proxyTargetClass) {
						AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
						return;
					}
				}
			}
		}
		if (!candidateFound && logger.isInfoEnabled()) {
			String name = getClass().getSimpleName();
			logger.info(String.format("%s was imported but no annotations were found " +
					"having both 'mode' and 'proxyTargetClass' attributes of type " +
					"AdviceMode and boolean respectively. This means that auto proxy " +
					"creator registration and configuration may not have occurred as " +
					"intended, and components may not be proxied as expected. Check to " +
					"ensure that %s has been @Import'ed on the same class where these " +
					"annotations are declared; otherwise remove the import of %s " +
					"altogether.", name, name, name));
		}
	}

}

AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);最终会尝试向容器中注册InfrastructureAdvisorAutoProxyCreator这个类

@Nullable
	public static BeanDefinition registerAutoProxyCreatorIfNecessary(
			BeanDefinitionRegistry registry, @Nullable Object source) {

		return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
	}

注册方式是使用RootBeanDefinition;
名称AUTO_PROXY_CREATOR_BEAN_NAME为org.springframework.aop.config.internalAutoProxyCreator,意为内部使用的动态代替创建器

RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);

ProxyTransactionManagementConfiguration的作用

ProxyTransactionManagementConfiguration是一个配置类,像容器中注册了3个Bean

  1. AnnotationTransactionAttributeSource
  2. TransactionInterceptor
  3. BeanFactoryTransactionAttributeSourceAdvisor
@Configuration(proxyBeanMethods = false)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {

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

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

}

InfrastructureAdvisorAutoProxyCreator

InfrastructureAdvisorAutoProxyCreator继承自SmartInstantiationAwareBeanPostProcessor,所以重点关注postProcessBeforeInstantiation和postProcessAfterInitialization;
这两个方法都在AbstractAutoProxyCreator中被实现

在这里插入图片描述
最终会在postProcessAfterInitialization中创建代理对象

@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
	if (bean != null) {
		Object cacheKey = getCacheKey(bean.getClass(), beanName);
		if (this.earlyProxyReferences.remove(cacheKey) != bean) {
			return wrapIfNecessary(bean, beanName, cacheKey);
		}
	}
	return bean;
}

比如我这里有一个UserService,testTx方法上加上@Transactional注解

public interface UserService extends IService<UserInfo> {

    void testTx();

}
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, UserInfo>
    implements UserService{

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void testTx() {
        System.out.println("testTx");
    }
}

最终在postProcessAfterInitialization#wrapIfNecessary中生成的proxy对象如下
在这里插入图片描述
观察到有个DynamicAdvisedIntercepter,这是一个通用的AOP回调,其中有个AdvisedSupport
AdvisedSupport 中又有个List<Advisor>
Advisor中可以获取Advice

private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {

	private final AdvisedSupport advised;
	
	@Override
	@Nullable
	public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
		
		// ...	
	
	}

}
public class AdvisedSupport extends ProxyConfig implements Advised {

	/**
	 * List of Advisors. If an Advice is added, it will be wrapped
	 * in an Advisor before being added to this List.
	 */
	private List<Advisor> advisors = new ArrayList<>();

}

public interface Advisor {

	/**
	 * Common placeholder for an empty {@code Advice} to be returned from
	 * {@link #getAdvice()} if no proper advice has been configured (yet).
	 * @since 5.0
	 */
	Advice EMPTY_ADVICE = new Advice() {};


	/**
	 * Return the advice part of this aspect. An advice may be an
	 * interceptor, a before advice, a throws advice, etc.
	 * @return the advice that should apply if the pointcut matches
	 * @see org.aopalliance.intercept.MethodInterceptor
	 * @see BeforeAdvice
	 * @see ThrowsAdvice
	 * @see AfterReturningAdvice
	 */
	Advice getAdvice();

	boolean isPerInstance();

}

和事务相关的Advice是TransactionInterceptor在这里插入图片描述

所有事务方法会被invoke方法拦截,这里列出几处核心逻辑

  1. 事务回滚和提交
if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
	// Standard transaction demarcation with getTransaction and commit/rollback calls.
	TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);

	Object retVal;
	try {
		// This is an around advice: Invoke the next interceptor in the chain.
		// This will normally result in a target object being invoked.
		retVal = invocation.proceedWithInvocation();
	}
	catch (Throwable ex) {
		// target invocation exception
		completeTransactionAfterThrowing(txInfo, ex);
		throw ex;
	}
	finally {
		cleanupTransactionInfo(txInfo);
	}

	if (retVal != null && vavrPresent && VavrDelegate.isVavrTry(retVal)) {
		// Set rollback-only in case of Vavr failure matching our rollback rules...
		TransactionStatus status = txInfo.getTransactionStatus();
		if (status != null && txAttr != null) {
			retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
		}
	}

	commitTransactionAfterReturning(txInfo);
	return retVal;
}
  1. 开始事务
private TransactionStatus startTransaction(TransactionDefinition definition, Object transaction,
		boolean debugEnabled, @Nullable SuspendedResourcesHolder suspendedResources) {

	boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
	DefaultTransactionStatus status = newTransactionStatus(
			definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
	doBegin(transaction, definition);
	prepareSynchronization(status, definition);
	return status;
}
  • 18
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值