Spring之事務原始碼

曹自標發表於2020-11-20

對@Transactional註解的類進行動態代理

同前文《Spring AOP原始碼分析》中分析動態代理入口一樣,都是在initializeBean時執行。

Object exposedObject = bean;
try {
	populateBean(beanName, mbd, instanceWrapper);
	exposedObject = initializeBean(beanName, exposedObject, mbd);
}

初始化時,呼叫applyBeanPostProcessorsAfterInitialization方法

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    ......
	if (mbd == null || !mbd.isSynthetic()) {
		wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
	}

	return wrappedBean;
}

其中processor為AnnotationAwareAspectJAutoProxyCreator時

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
		throws BeansException {

	Object result = existingBean;
	for (BeanPostProcessor processor : getBeanPostProcessors()) {
	    //AnnotationAwareAspectJAutoProxyCreator
		Object current = processor.postProcessAfterInitialization(result, beanName);
		if (current == null) {
			return result;
		}
		result = current;
	}
	return result;
}

因AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator ,AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator,AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator,調父類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;
}

呼叫AbstractAutoProxyCreator#wrapIfNecessary()

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
	if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
		return bean;
	}
	if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
		return bean;
	}
	if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}

	// Create proxy if we have advice.
	Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
	if (specificInterceptors != DO_NOT_PROXY) {
		this.advisedBeans.put(cacheKey, Boolean.TRUE);
		Object proxy = createProxy(
				bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
		this.proxyTypes.put(cacheKey, proxy.getClass());
		return proxy;
	}

	this.advisedBeans.put(cacheKey, Boolean.FALSE);
	return bean;
}

最後返回specificInterceptors不為null,為何不為null,下一段落具體分析。開始建立Proxy。呼叫AbstractAutoProxyCreator#createProxy(),set
advisors和targetSource

	protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
			@Nullable Object[] specificInterceptors, TargetSource targetSource) {

		ProxyFactory proxyFactory = new ProxyFactory();
		proxyFactory.copyFrom(this);
        ......
        Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
		proxyFactory.addAdvisors(advisors);
        proxyFactory.setTargetSource(targetSource);
		customizeProxyFactory(proxyFactory);
        ......
		return proxyFactory.getProxy(getProxyClassLoader());
	}

ProxyCreatorSupport#createAopProxy() --> DefaultAopProxyFactory#createAopProxy(),判斷走JDK動態代理還是CGLIB代理,此時由於代理是類,返回new ObjenesisCglibAopProxy(config)

@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
	if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
		Class<?> targetClass = config.getTargetClass();
		if (targetClass == null) {
			throw new AopConfigException("TargetSource cannot determine target class: " +
					"Either an interface or a target is required for proxy creation.");
		}
		if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
			return new JdkDynamicAopProxy(config);
		}
		return new ObjenesisCglibAopProxy(config);
	}
	else {
		return new JdkDynamicAopProxy(config);
	}
}

走CglibAopProxy#getProxy()

	@Override
	public Object getProxy(@Nullable ClassLoader classLoader) {
		if (logger.isTraceEnabled()) {
			logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
		}

		try {
			Class<?> rootClass = this.advised.getTargetClass();
			Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");

			Class<?> proxySuperClass = rootClass;
			......

			// Validate the class, writing log messages as necessary.
			validateClassIfNecessary(proxySuperClass, classLoader);

			// Configure CGLIB Enhancer...
			Enhancer enhancer = createEnhancer();
			if (classLoader != null) {
				enhancer.setClassLoader(classLoader);
				if (classLoader instanceof SmartClassLoader &&
						((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
					enhancer.setUseCache(false);
				}
			}
			enhancer.setSuperclass(proxySuperClass);
			enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
			enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
			enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));

			Callback[] callbacks = getCallbacks(rootClass);
			Class<?>[] types = new Class<?>[callbacks.length];
			for (int x = 0; x < types.length; x++) {
				types[x] = callbacks[x].getClass();
			}
			// fixedInterceptorMap only populated at this point, after getCallbacks call above
			enhancer.setCallbackFilter(new ProxyCallbackFilter(
					this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
			enhancer.setCallbackTypes(types);

			// Generate the proxy class and create a proxy instance.
			return createProxyClassAndInstance(enhancer, callbacks);
		}
		......
	}
protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
	enhancer.setInterceptDuringConstruction(false);
	enhancer.setCallbacks(callbacks);
	return (this.constructorArgs != null && this.constructorArgTypes != null ?
			enhancer.create(this.constructorArgTypes, this.constructorArgs) :
			enhancer.create());
}

獲取Advisor詳細過程

既然specificInterceptors不為null,便從下面開始逆向分析

Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);

this為AnnotationAwareAspectJAutoProxyCreator,但此類並沒有getAdvicesAndAdvisorsForBean方法,於是開始找父類,呼叫AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean()

@Override
@Nullable
protected Object[] getAdvicesAndAdvisorsForBean(
		Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
	List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
	if (advisors.isEmpty()) {
		return DO_NOT_PROXY;
	}
	return advisors.toArray();
}

DO_NOT_PROXY為null,既然最後取不為null,所以肯定findEligibleAdvisors不為null。找AbstractAdvisorAutoProxyCreator#findEligibleAdvisors()方法:

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
	List<Advisor> candidateAdvisors = findCandidateAdvisors();
	List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
	extendAdvisors(eligibleAdvisors);
	if (!eligibleAdvisors.isEmpty()) {
		eligibleAdvisors = sortAdvisors(eligibleAdvisors);
	}
	return eligibleAdvisors;
}

此時可使用idea的Evaluate Expression ,檢視findCandidateAdvisors()的結果,發現事務的Advisor已經在裡面,便可先檢視AbstractAdvisorAutoProxyCreator#findCandidateAdvisors()

protected List<Advisor> findCandidateAdvisors() {
	return this.advisorRetrievalHelper.findAdvisorBeans();
}

呼叫BeanFactoryAdvisorRetrievalHelper#findAdvisorBeans();此時cachedAdvisorBeanNames字串陣列中有一個值"org.springframework.transaction.config.internalTransactionAdvisor",直接在IOC容器中根據name獲取Bean,新增到advisors中。

public List<Advisor> findAdvisorBeans() {
	// Determine list of advisor bean names, if not cached already.
	String[] advisorNames = this.cachedAdvisorBeanNames;
	if (advisorNames == null) {
		......
	}
	if (advisorNames.length == 0) {
		return new ArrayList<>();
	}

	List<Advisor> advisors = new ArrayList<>();
	for (String name : advisorNames) {
		if (isEligibleBean(name)) {
			if (this.beanFactory.isCurrentlyInCreation(name)) {
				......
			}
			else {
				try {
					advisors.add(this.beanFactory.getBean(name, Advisor.class));
				}
			}
		}
	}
}

所以先檢視cachedAdvisorBeanNames是什麼時候被賦值的。而cachedAdvisorBeanNames被賦值只有上面方法advisorNames == null時:

public List<Advisor> findAdvisorBeans() {
	if (advisorNames == null) {
		advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
				this.beanFactory, Advisor.class, true, false);
		this.cachedAdvisorBeanNames = advisorNames;
	}
}

所以檢視BeanFactoryUtils.beanNamesForTypeIncludingAncestors()。

	public static String[] beanNamesForTypeIncludingAncestors(
			ListableBeanFactory lbf, Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {

		String[] result = lbf.getBeanNamesForType(type, includeNonSingletons, allowEagerInit);
        ......
		return result;
	}

Evaluate知lbf.getBeanNamesForType()得到結果,於是進ListableBeanFactory#getBeanNamesForType()方法

@Override
public String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
	if (!isConfigurationFrozen() || type == null || !allowEagerInit) {
		return doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, allowEagerInit);
	}
}

由於前面allowEagerInit傳值為false,!allowEagerInit所以為true。所以呼叫ListableBeanFactory#doGetBeanNamesForType()根據type獲取beanName

  1. 遍歷所有BeanDefinition
  2. 將beanName, type, allowFactoryBeanInit入參呼叫AbstractBeanFactory#isTypeMatch()方法
  3. 滿足type(org.springframework.aop.Advisor)的beanName 加入result集合中進行返回
private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
	List<String> result = new ArrayList<>();

	for (String beanName : this.beanDefinitionNames) {
		if (!isAlias(beanName)) {
			try {
				RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				// Only check bean definition if it is complete.
				if (!mbd.isAbstract() && (allowEagerInit ||
						(mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading()) &&
								!requiresEagerInitForType(mbd.getFactoryBeanName()))) {
					//false
					boolean isFactoryBean = isFactoryBean(beanName, mbd);
					BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
					boolean matchFound = false;
					//false
					boolean allowFactoryBeanInit = (allowEagerInit || containsSingleton(beanName));
					//false
					boolean isNonLazyDecorated = (dbd != null && !mbd.isLazyInit());
					if (!isFactoryBean) {
						if (includeNonSingletons || isSingleton(beanName, mbd, dbd)) {
							matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
						}
					}
					
					if (matchFound) {
						result.add(beanName);
					}
				}
			}
		}
	}
    ......

	return StringUtils.toStringArray(result);
}

其中isTypeMatch方法執行結果為true

protected boolean isTypeMatch(String name, ResolvableType typeToMatch, boolean allowFactoryBeanInit)
		throws NoSuchBeanDefinitionException {


	// Attempt to get the actual ResolvableType for the bean.
	ResolvableType beanType = null;

	// We don't have an exact type but if bean definition target type or the factory
	// method return type matches the predicted type then we can use that.
	if (beanType == null) {
		ResolvableType definedType = mbd.targetType;
		if (definedType == null) {
			definedType = mbd.factoryMethodReturnType;
		}
		if (definedType != null && definedType.resolve() == predictedType) {
			beanType = definedType;
		}
	}

	// If we have a bean type use it so that generics are considered
	if (beanType != null) {
		return typeToMatch.isAssignableFrom(beanType);
	}
}

BeanFactoryAdvisorRetrievalHelper.cachedAdvisorBeanNames賦值後,回頭看AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors()。其中註釋也可看出AnnotationAwareAspectJAutoProxyCreator.aspectJAdvisorsBuilder.buildAspectJAdvisors()是獲取所有@Aspect 註解裡面的前置、後置、環繞等通知,最後包裝的advisors

@Override
protected List<Advisor> findCandidateAdvisors() {
	// Add all the Spring advisors found according to superclass rules.
	List<Advisor> advisors = super.findCandidateAdvisors();
	// Build Advisors for all AspectJ aspects in the bean factory.
	if (this.aspectJAdvisorsBuilder != null) {
		advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
	}
	return advisors;
}

所以返回AbstractAdvisorAutoProxyCreator#findEligibleAdvisors()中,會進行一次篩選

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
	List<Advisor> candidateAdvisors = findCandidateAdvisors();
	List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
	extendAdvisors(eligibleAdvisors);
	if (!eligibleAdvisors.isEmpty()) {
		eligibleAdvisors = sortAdvisors(eligibleAdvisors);
	}
	return eligibleAdvisors;
}

呼叫AbstractAdvisorAutoProxyCreator#findAdvisorsThatCanApply()

protected List<Advisor> findAdvisorsThatCanApply(
		List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {

	ProxyCreationContext.setCurrentProxiedBeanName(beanName);
	try {
		return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
	}
	finally {
		ProxyCreationContext.setCurrentProxiedBeanName(null);
	}
}

具體在AopUtils#findAdvisorsThatCanApply(),和AopUtils#canApply()中過濾實現

public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
	if (candidateAdvisors.isEmpty()) {
		return candidateAdvisors;
	}
	List<Advisor> eligibleAdvisors = new ArrayList<>();
	for (Advisor candidate : candidateAdvisors) {
		if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
			eligibleAdvisors.add(candidate);
		}
	}
	boolean hasIntroductions = !eligibleAdvisors.isEmpty();
	for (Advisor candidate : candidateAdvisors) {
		if (candidate instanceof IntroductionAdvisor) {
			// already processed
			continue;
		}
		if (canApply(candidate, clazz, hasIntroductions)) {
			eligibleAdvisors.add(candidate);
		}
	}
	return eligibleAdvisors;
}

所以最後順著理流程是:

  • 在最開始例項化AnnotationAwareAspectJAutoProxyCreator之前,在AbstractAutowireCapableBeanFactory#createBean()中呼叫在AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation(),最後呼叫AbstractAutoProxyCreator#postProcessBeforeInstantiation()進行例項化前處理。
  • 而在判斷是否需要跳過時(AspectJAwareAdvisorAutoProxyCreator#shouldSkip()),會去找符合條件的Advisor。
  • 找符合條件的Advisor這個過程主要通過傳入Advisor.class type,最後在DefaultListableFactory#doGetBeanNamesForType()中,先取出所有BeanDefinition進行遍歷,將beanName, type, allowFactoryBeanInit入參呼叫AbstractBeanFactory#isTypeMatch()方法,滿足type(org.springframework.aop.Advisor)的beanName 加入result集合中進行返回。
  • 上面得到的結果賦值給BeanFactoryAdvisorRetrievalHelper.cachedAdvisorBeanNames
  • cachedAdvisorBeanNames不為null便會根據beanName和Advisor.class type從IOC容器中取出Bean,返回findCandidateAdvisors()
  • findCandidateAdvisors()包含了@Aspect註解的Advisors,通過findAdvisorsThatCanApply方法進行過濾出僅事務相關的Advisor

beanName為org.springframework.transaction.config.internalTransactionAdvisor 的Bean具體生成過程

總結:

  • 在ConfigurationClassParser#parse()中會對deferredImportSelectorHandler進行處理(在處理@ComponentScan 自己所寫@Component的類後)
  • 處理過程中會呼叫SpringFactoriesLoader#loadFactoryNames(),去查詢所有jar下面META-INF/spring.factories中key為org.springframework.boot.autoconfigure.EnableAutoConfiguration的值
  • ConfigurationClassPostProcessor#processConfigBeanDefinitions()中loadBeanDefinitions對TransactionAutoConfiguration進行BeanDefinition的載入,並註冊IOC容器

TransactionAutoConfiguration的BeanDefinition載入解析

TransactionAutoConfiguration的自動配置

呼叫鏈:

AbstractApplicationContext#refresh() --> AbstractApplicationContext#invokeBeanFactoryPostProcessors() --> PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors() --> PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors() --> ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry()--> ConfigurationClassPostProcessor#processConfigBeanDefinitions() --> ConfigurationClassPostProcessor#parse() --> ConfigurationClassParser#process() --> ConfigurationClassParser$DeferredImportSelectorGroupingHandler#processGroupImports() --> ConfigurationClassParser#processImports() --> ConfigurationClassParser#processConfigurationClass() --> ConfigurationClassParser#doProcessConfigurationClass()

ConfigurationClassParser#parse() 對延遲ImportSelector進行處理

private final DeferredImportSelectorHandler deferredImportSelectorHandler = new DeferredImportSelectorHandler();

public void parse(Set<BeanDefinitionHolder> configCandidates) {
	this.deferredImportSelectorHandler.process();
}

呼叫DeferredImportSelectorGroupingHandler#processGroupImports()

public void process() {
	List<DeferredImportSelectorHolder> deferredImports = this.deferredImportSelectors;
	this.deferredImportSelectors = null;
	try {
		if (deferredImports != null) {
			DeferredImportSelectorGroupingHandler handler = new DeferredImportSelectorGroupingHandler();
			deferredImports.sort(DEFERRED_IMPORT_COMPARATOR);
			// 給ConfigurationClassParser.groupings賦值
			deferredImports.forEach(handler::register);
			// DeferredImportSelectorGroupingHandler處理
			handler.processGroupImports();
		}
	}
	finally {
		this.deferredImportSelectors = new ArrayList<>();
	}

主要handler.processGroupImports()中 grouping.getImports()會查詢出所有ConfigurationClassParser$DeferredImportSelectorGroupingHandler中的imports

public void processGroupImports() {
	for (DeferredImportSelectorGrouping grouping : this.groupings.values()) {
		
		grouping.getImports().forEach(entry -> {
			ConfigurationClass configurationClass = this.configurationClasses.get(entry.getMetadata());
			try {
				processImports(configurationClass, asSourceClass(configurationClass, exclusionFilter),
						Collections.singleton(asSourceClass(entry.getImportClassName(), exclusionFilter)),
						exclusionFilter, false);
			}
		}
	}
}

ConfigurationClassParser$DeferredImportSelectorGroupingHandler#getImports()

public Iterable<Group.Entry> getImports() {
	for (DeferredImportSelectorHolder deferredImport : this.deferredImports) {
		this.group.process(deferredImport.getConfigurationClass().getMetadata(),
				deferredImport.getImportSelector());
	}
	return this.group.selectImports();
}

會呼叫AutoConfigurationImportSelector#process()

public void process(AnnotationMetadata annotationMetadata, DeferredImportSelector deferredImportSelector) {
	AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationImportSelector) deferredImportSelector)
			.getAutoConfigurationEntry(annotationMetadata);
	this.autoConfigurationEntries.add(autoConfigurationEntry);
	for (String importClassName : autoConfigurationEntry.getConfigurations()) {
		this.entries.putIfAbsent(importClassName, annotationMetadata);
	}
}

會呼叫AutoConfigurationImportSelector#getAutoConfigurationEntry()

protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
	List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
	......
	return new AutoConfigurationEntry(configurations, exclusions);
}

其中AutoConfigurationImportSelector#getCandidateConfigurations()會查詢所有jar下面META-INF/spring.factories,進行loadFactoryNames。

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
	List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
			getBeanClassLoader());
	return configurations;
}

SpringFactoriesLoader#loadFactoryNames()

public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
	......
	return loadSpringFactories(classLoaderToUse).getOrDefault(factoryTypeName, Collections.emptyList());
}

SpringFactoriesLoader#loadSpringFactories()

private static Map<String, List<String>> loadSpringFactories(ClassLoader classLoader) {

	result = new HashMap<>();
	try {
		Enumeration<URL> urls = classLoader.getResources(FACTORIES_RESOURCE_LOCATION);
		while (urls.hasMoreElements()) {
			URL url = urls.nextElement();
			UrlResource resource = new UrlResource(url);
			Properties properties = PropertiesLoaderUtils.loadProperties(resource);
			for (Map.Entry<?, ?> entry : properties.entrySet()) {
				String factoryTypeName = ((String) entry.getKey()).trim();
				String[] factoryImplementationNames =
						StringUtils.commaDelimitedListToStringArray((String) entry.getValue());
				for (String factoryImplementationName : factoryImplementationNames) {
					result.computeIfAbsent(factoryTypeName, key -> new ArrayList<>())
							.add(factoryImplementationName.trim());
				}
			}
		}
	}
	
	return result;
}

其中spring-boot-autoconfigure-XX.jar下面META-INF/spring.factories檔案中就有:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration

附:其中ConfigurationClassParser.groupings賦值,是在ConfigurationClassParser#register()執行的

public void register(DeferredImportSelectorHolder deferredImport) {
	Class<? extends Group> group = deferredImport.getImportSelector().getImportGroup();
	DeferredImportSelectorGrouping grouping = this.groupings.computeIfAbsent(
			(group != null ? group : deferredImport),
			key -> new DeferredImportSelectorGrouping(createGroup(group)));
	grouping.add(deferredImport);
	this.configurationClasses.put(deferredImport.getConfigurationClass().getMetadata(),
			deferredImport.getConfigurationClass());
}
TransactionAutoConfiguration進行@Configuration處理

此過程主要是處理TransactionAutoConfiguration內部類EnableTransactionManagement

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(PlatformTransactionManager.class)
@AutoConfigureAfter({ JtaAutoConfiguration.class, HibernateJpaAutoConfiguration.class,
		DataSourceTransactionManagerAutoConfiguration.class, Neo4jDataAutoConfiguration.class })
@EnableConfigurationProperties(TransactionProperties.class)
public class TransactionAutoConfiguration {

	@Configuration(proxyBeanMethods = false)
	@ConditionalOnBean(TransactionManager.class)
	@ConditionalOnMissingBean(AbstractTransactionManagementConfiguration.class)
	public static class EnableTransactionManagementConfiguration {

		@Configuration(proxyBeanMethods = false)
		@EnableTransactionManagement(proxyTargetClass = false)
		@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false",
				matchIfMissing = false)
		public static class JdkDynamicAutoProxyConfiguration {

		}

		@Configuration(proxyBeanMethods = false)
		@EnableTransactionManagement(proxyTargetClass = true)
		@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
				matchIfMissing = true)
		public static class CglibAutoProxyConfiguration {

		}

	}

}

在ConfigurationClassParser#doProcessConfigurationClass()處理內部類時

protected final SourceClass doProcessConfigurationClass(
		ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
		throws IOException {

	if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
		// Recursively process any member (nested) classes first
		processMemberClasses(configClass, sourceClass, filter);
	}
}

呼叫ConfigurationClassParser#processMemberClasses()時,內部類有兩個,本文主要看EnableTransactionManagement類處理邏輯,TransactionTemplateConfiguration進行類似處理

private void processMemberClasses(ConfigurationClass configClass, SourceClass sourceClass,
		Predicate<String> filter) throws IOException {
	if (!memberClasses.isEmpty()) {
		for (SourceClass candidate : candidates) {
			if (this.importStack.contains(configClass)) {
				......
			}
			else {
				this.importStack.push(configClass);
				try {
					processConfigurationClass(candidate.asConfigClass(configClass), filter);
				}
				finally {
					this.importStack.pop();
				}
			}
		}
	}
}

進入內部類EnableTransactionManagementConfiguration的@Configuration的處理邏輯,呼叫ConfigurationClassParser#processConfigurationClass(),仍走到ConfigurationClassParser#doProcessConfigurationClass()處理
而通過上面EnableTransactionManagementConfiguration的程式碼可知,它有兩個內部類,其中JdkDynamicAutoProxyConfiguration的proxyTargetClass 預設false,CglibAutoProxyConfiguration預設為true,所以預設CGLIB代理

而這裡所以仍執行TransactionAutoConfiguration$EnableTransactionManagementConfiguration 的processMemberClasses邏輯
其中看EnableTransactionManagement程式碼可知, Import了TransactionManagementConfigurationSelector

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

所以在ConfigurationClassParser中呼叫TransactionManagementConfigurationSelector#selectImports()

private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
		Collection<SourceClass> importCandidates, Predicate<String> exclusionFilter,
		boolean checkForCircularImports) {

	if (importCandidates.isEmpty()) {
		return;
	}

	if (checkForCircularImports && isChainedImportOnStack(configClass)) {
		......
	}
	else {
		this.importStack.push(configClass);
		try {
			for (SourceClass candidate : importCandidates) {
				if (candidate.isAssignable(ImportSelector.class)) {
					
					if (selector instanceof DeferredImportSelector) {
					
					}
					else {
						String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());

					}
				}
			}
		}
	}
}

此時的adviceMode為proxy

public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {

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

返回的imports陣列中包括org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration

此時再對這兩個imports陣列進行ConfigurationClassParser#processImports操作

對AbstractTransactionManagementConfiguration進行processConfigurationClass操作。

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

}

會執行doProcessConfigurationClass中@Bean處理邏輯,其中String TRANSACTION_ADVISOR_BEAN_NAME = "org.springframework.transaction.config.internalTransactionAdvisor";

protected final SourceClass doProcessConfigurationClass(
		ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
		throws IOException {

	// Process individual @Bean methods
	Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
	for (MethodMetadata methodMetadata : beanMethods) {
		configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
	}
}

於是往ConfigurationClassParser.configurationClasses中進行快取,在下一步loadBeanDefinitions中使用

private final Map<ConfigurationClass, ConfigurationClass> configurationClasses = new LinkedHashMap<>();

protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) throws IOException {
	this.configurationClasses.put(configClass, configClass);
}
loadBeanDefinitions

this.reader.loadBeanDefinitions(configClasses)進行BeanDefinition的載入,並註冊到IOC容器

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
    this.reader.loadBeanDefinitions(configClasses);
}
public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
	TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
	for (ConfigurationClass configClass : configurationModel) {
		loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
	}
}

重點在下面ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForConfigurationClass()方法。當從configClass.getBeanMethods()可以獲取到上一步beanMethod

private void loadBeanDefinitionsForConfigurationClass(
		ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {

	if (trackedConditionEvaluator.shouldSkip(configClass)) {
		String beanName = configClass.getBeanName();
		if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {
			this.registry.removeBeanDefinition(beanName);
		}
		this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());
		return;
	}

	if (configClass.isImported()) {
		registerBeanDefinitionForImportedConfigurationClass(configClass);
	}
	for (BeanMethod beanMethod : configClass.getBeanMethods()) {
		loadBeanDefinitionsForBeanMethod(beanMethod);
	}

	loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
	loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}

進行loadBeanDefinitionsForBeanMethod,通過建立ConfigurationClassBeanDefinition,設定一些屬性值,最後向IOC容器中進行註冊

private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {
	......

	ConfigurationClassBeanDefinition beanDef = new ConfigurationClassBeanDefinition(configClass, metadata, beanName);
	beanDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource()));

	if (metadata.isStatic()) {
		......
	}
	else {
		// instance @Bean method
		beanDef.setFactoryBeanName(configClass.getBeanName());
		beanDef.setUniqueFactoryMethodName(methodName);
	}

	beanDef.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
	beanDef.setAttribute(org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor.
			SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE);

	AnnotationConfigUtils.processCommonDefinitionAnnotations(beanDef, metadata);


	// Replace the original bean definition with the target one, if necessary
	BeanDefinition beanDefToRegister = beanDef;
	if (proxyMode != ScopedProxyMode.NO) {
		BeanDefinitionHolder proxyDef = ScopedProxyCreator.createScopedProxy(
				new BeanDefinitionHolder(beanDef, beanName), this.registry,
				proxyMode == ScopedProxyMode.TARGET_CLASS);
		beanDefToRegister = new ConfigurationClassBeanDefinition(
				(RootBeanDefinition) proxyDef.getBeanDefinition(), configClass, metadata, beanName);
	}

	this.registry.registerBeanDefinition(beanName, beanDefToRegister);
}

呼叫DefaultListableBeanFactory#registerBeanDefinition()將BeanDefinition進行儲存

private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
	@Override
	public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
			throws BeanDefinitionStoreException {

	
		BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
		if (existingDefinition != null) {
			......
		}
		else {
			if (hasBeanCreationStarted()) {
				// Cannot modify startup-time collection elements anymore (for stable iteration)
				synchronized (this.beanDefinitionMap) {
					this.beanDefinitionMap.put(beanName, beanDefinition);
				}
			}
		}
	}
}

攔截過程

呼叫到@Transactional註解的類或方法時,呼叫CglibAopProxy$DynamicAdvisedInterceptor#()

public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
	TargetSource targetSource = this.advised.getTargetSource();
	try {
		
		// Check whether we only have one InvokerInterceptor: that is,
		// no real advice, but just reflective invocation of the target.
		if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
			......
		}
		else {
			// We need to create a method invocation...
			retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
		}
		retVal = processReturnType(proxy, target, method, retVal);
		return retVal;
	}
	finally {
		if (target != null && !targetSource.isStatic()) {
			targetSource.releaseTarget(target);
		}
		if (setProxyContext) {
			// Restore old proxy.
			AopContext.setCurrentProxy(oldProxy);
		}
	}
}

呼叫ReflectiveMethodInvocation#process()

public Object proceed() throws Throwable {

	Object interceptorOrInterceptionAdvice =
			this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
	if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
		......
	}
	else {
		// It's an interceptor, so we just invoke it: The pointcut will have
		// been evaluated statically before this object was constructed.
		return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
	}
}

呼叫TransactionInterceptor#invoke()

	public Object invoke(MethodInvocation invocation) throws Throwable {
		......
		return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
	}

呼叫TransactionAspectSupport#invokeWithinTransaction()

protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
		final InvocationCallback invocation) throws Throwable {

	// If the transaction attribute is null, the method is non-transactional.
	// 如果transaction attribute為空,該方法就是非事務(非程式設計式事務)
	TransactionAttributeSource tas = getTransactionAttributeSource();
	final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
	final TransactionManager tm = determineTransactionManager(txAttr);

	......

	PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
	final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
    // 標準宣告式事務:如果事務屬性為空 或者 非回撥偏向的事務管理器
	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;
	}

	else {
		Object result;
		final ThrowableHolder throwableHolder = new ThrowableHolder();

		// It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
		try {
			result = ((CallbackPreferringPlatformTransactionManager) ptm).execute(txAttr, status -> {
				TransactionInfo txInfo = prepareTransactionInfo(ptm, txAttr, joinpointIdentification, status);
				try {
					Object retVal = invocation.proceedWithInvocation();
					if (retVal != null && vavrPresent && VavrDelegate.isVavrTry(retVal)) {
						// Set rollback-only in case of Vavr failure matching our rollback rules...
						retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
					}
					return retVal;
				}
				catch (Throwable ex) {
					.....
				}
				finally {
					cleanupTransactionInfo(txInfo);
				}
			});
		}
		.......
		return result;
	}
}

呼叫TransactionAspectSupport#createTransactionIfNecessary()判斷是否有必要建立事務

protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm,
		@Nullable TransactionAttribute txAttr, final String joinpointIdentification) {

	// If no name specified, apply method identification as transaction name.
	if (txAttr != null && txAttr.getName() == null) {
		txAttr = new DelegatingTransactionAttribute(txAttr) {
			@Override
			public String getName() {
				return joinpointIdentification;
			}
		};
	}

	TransactionStatus status = null;
	if (txAttr != null) {
		if (tm != null) {
			status = tm.getTransaction(txAttr);
		}
	}
	return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
}

具體是否建立事務,傳播級別及隔離級別處理在AbstractPlatformTransactionManager#getTransaction()方法中

@Override
public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
		throws TransactionException {

	// Use defaults if no transaction definition given.
	TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults());
    //DataSouce或JPA。mysql會呼叫DataSourceTransactionManager#doGetTransaction()
	Object transaction = doGetTransaction();
	boolean debugEnabled = logger.isDebugEnabled();

	if (isExistingTransaction(transaction)) {
		// Existing transaction found -> check propagation behavior to find out how to behave.
		return handleExistingTransaction(def, transaction, debugEnabled);
	}


	// No existing transaction found -> check propagation behavior to find out how to proceed.
	if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
		throw new IllegalTransactionStateException(
				"No existing transaction found for transaction marked with propagation 'mandatory'");
	}
	else if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
			def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
			def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
		SuspendedResourcesHolder suspendedResources = suspend(null);
		if (debugEnabled) {
			logger.debug("Creating new transaction with name [" + def.getName() + "]: " + def);
		}
		try {
			return startTransaction(def, transaction, debugEnabled, suspendedResources);
		}
		catch (RuntimeException | Error ex) {
			resume(null, suspendedResources);
			throw ex;
		}
	}
	else {
		// Create "empty" transaction: no actual transaction, but potentially synchronization.
		if (def.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
			logger.warn("Custom isolation level specified but no actual transaction initiated; " +
					"isolation level will effectively be ignored: " + def);
		}
		boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
		return prepareTransactionStatus(def, null, true, newSynchronization, debugEnabled, null);
	}
}

獲取到transaction後,返回transactionAspectSupport#invokeWithinTransaction()看提交邏輯

先執行環繞增強,可自定義增強功能

invocation.proceedWithInvocation();

如果丟擲異常,進行completeTransactionAfterThrowing處理,根據事務定義的,該異常需要回滾就回滾,否則提交事務

protected void completeTransactionAfterThrowing(@Nullable TransactionInfo txInfo, Throwable ex) {
	if (txInfo != null && txInfo.getTransactionStatus() != null) {

		if (txInfo.transactionAttribute != null && txInfo.transactionAttribute.rollbackOn(ex)) {
			try {
				txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
			}
		}
	}
}

執行commitTransactionAfterReturning()

commitTransactionAfterReturning(txInfo)
protected void commitTransactionAfterReturning(@Nullable TransactionInfo txInfo) {
	if (txInfo != null && txInfo.getTransactionStatus() != null) {
		txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
	}
}

呼叫AbstractPlatformTransactionManager#commit()

@Override
public final void commit(TransactionStatus status) throws TransactionException {
	if (status.isCompleted()) {
		throw new IllegalTransactionStateException(
				"Transaction is already completed - do not call commit or rollback more than once per transaction");
	}

	DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
	if (defStatus.isLocalRollbackOnly()) {
		if (defStatus.isDebug()) {
			logger.debug("Transactional code has requested rollback");
		}
		processRollback(defStatus, false);
		return;
	}

	if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
		if (defStatus.isDebug()) {
			logger.debug("Global transaction is marked as rollback-only but transactional code requested commit");
		}
		processRollback(defStatus, true);
		return;
	}

	processCommit(defStatus);
}

正常建立事務的執行AbstractPlatformTransactionManager#processCommit()

private void processCommit(DefaultTransactionStatus status) throws TransactionException {
	try {
		boolean beforeCompletionInvoked = false;

		try {
			boolean unexpectedRollback = false;
			prepareForCommit(status);
			triggerBeforeCommit(status);
			triggerBeforeCompletion(status);
			beforeCompletionInvoked = true;

			if (status.hasSavepoint()) {
				if (status.isDebug()) {
					logger.debug("Releasing transaction savepoint");
				}
				unexpectedRollback = status.isGlobalRollbackOnly();
				status.releaseHeldSavepoint();
			}
			else if (status.isNewTransaction()) {
				if (status.isDebug()) {
					logger.debug("Initiating transaction commit");
				}
				unexpectedRollback = status.isGlobalRollbackOnly();
				doCommit(status);
			}
			else if (isFailEarlyOnGlobalRollbackOnly()) {
				unexpectedRollback = status.isGlobalRollbackOnly();
			}

			// Throw UnexpectedRollbackException if we have a global rollback-only
			// marker but still didn't get a corresponding exception from commit.
			if (unexpectedRollback) {
				throw new UnexpectedRollbackException(
						"Transaction silently rolled back because it has been marked as rollback-only");
			}
		}
		catch (UnexpectedRollbackException ex) {
			// can only be caused by doCommit
			triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
			throw ex;
		}
		catch (TransactionException ex) {
			// can only be caused by doCommit
			if (isRollbackOnCommitFailure()) {
				doRollbackOnCommitException(status, ex);
			}
			else {
				triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
			}
			throw ex;
		}
		catch (RuntimeException | Error ex) {
			if (!beforeCompletionInvoked) {
				triggerBeforeCompletion(status);
			}
			doRollbackOnCommitException(status, ex);
			throw ex;
		}

		// Trigger afterCommit callbacks, with an exception thrown there
		// propagated to callers but the transaction still considered as committed.
		try {
			triggerAfterCommit(status);
		}
		finally {
			triggerAfterCompletion(status, TransactionSynchronization.STATUS_COMMITTED);
		}

	}
	finally {
		cleanupAfterCompletion(status);
	}
}

執行DataSourceTransactionManager#doCommit(),獲取jdbc的connection,進行事務命令提交

@Override
protected void doCommit(DefaultTransactionStatus status) {
	DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
	Connection con = txObject.getConnectionHolder().getConnection();
	if (status.isDebug()) {
		logger.debug("Committing JDBC transaction on Connection [" + con + "]");
	}
	try {
		con.commit();
	}
	catch (SQLException ex) {
		throw translateException("JDBC commit", ex);
	}
}

事務隔離級別及傳播級別定義

public interface TransactionDefinition {

	// 支援當前事務;如果不存在,建立一個新的。
	int PROPAGATION_REQUIRED = 0;

    //支援當前事務;如果不存在事務,則以非事務方式執行
	int PROPAGATION_SUPPORTS = 1;

	//支援當前事務;如果當前事務不存在,丟擲異常。
	int PROPAGATION_MANDATORY = 2;

	//建立一個新事務,如果存在當前事務,則掛起當前事務
	int PROPAGATION_REQUIRES_NEW = 3;

	//不支援當前事務,存在事務掛起當前事務;始終以非事務方式執行
	int PROPAGATION_NOT_SUPPORTED = 4;

	//不支援當前事務;如果當前事務存在,丟擲異常。
	int PROPAGATION_NEVER = 5;

	//如果當前事務存在,則在巢狀事務中執行,如果當前沒有事務,類似PROPAGATION_REQUIRED(建立一個新的)
	int PROPAGATION_NESTED = 6;


	/**
	 * Use the default isolation level of the underlying datastore.
	 * All other levels correspond to the JDBC isolation levels.
	 * @see java.sql.Connection
	 */
	int ISOLATION_DEFAULT = -1;

	//讀未提交
	int ISOLATION_READ_UNCOMMITTED = 1;  // same as java.sql.Connection.TRANSACTION_READ_UNCOMMITTED;

	//讀已提交
	int ISOLATION_READ_COMMITTED = 2;  // same as java.sql.Connection.TRANSACTION_READ_COMMITTED;

	// 可重複讀
	int ISOLATION_REPEATABLE_READ = 4;  // same as java.sql.Connection.TRANSACTION_REPEATABLE_READ;

	//序列
	int ISOLATION_SERIALIZABLE = 8;  // same as java.sql.Connection.TRANSACTION_SERIALIZABLE;


	/**
	 * Use the default timeout of the underlying transaction system,
	 * or none if timeouts are not supported.
	 */
	int TIMEOUT_DEFAULT = -1;
}

附:可參考https://www.cnblogs.com/dennyzhangdd/p/9602673.html這篇博文,裡面有個時序圖不錯

相關文章