Spring事务(一)【原理浅析】

Scroll Down

什么是事务

事务是数据库操作的最小单元,是作为单个逻辑单元执行的一系列操作;这些操作作为一个整体向系统提交,要么都执行,要么都不执行;事务是一组不可分割的操作集合。通俗点说为了达到某个目的而做了一系列的操作,要么一起成功,要么一起失败。

事务的特性

  • 原子性:事务中所有操作是不可再分割的原子单位。事务中操作要么全部执行成功,要么全部执行失败。
  • 一致性:事务执行后,数据库的状态与其业务规则保持一致。
  • 隔离性:并发操作中,不同的事务之间应该隔离开来,使每个并发中的事务不会相互干扰。
  • 持久性:一旦事务提交成功,事务中所有数据都被持久化到数据库中,即使提交事务后数据库崩溃,在数据库在重启后也必须保证通过某种机制进行恢复数据。

事务的隔离级别

数据库事务的隔离级别有4种,由低到高分别为Read uncommitted、Read committed、Repeatable Read、Serializable。在事务的并发操作中可能会出现脏读、不可重复读、幻读、事务丢失。

  • 脏读(读取了未提交的新事务,然后被回滚了):事务A读取了事务B中尚未提交的数据。如果B事务回滚,则A就读取了错误的数据。
  • 不可重复读(读取了提交的新事务,指更新操作):在对数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔时,被另一个事务修改并提交了。
  • 幻读(读取了提交的新事物,值新增和删除操作)在事务A多次读取中,事务B做了新增和删除操作,造成事务A多次读取的结果不一致。
  • Read uncommitted:允许一个事务读取另一个事务未提交的数据。会产生脏读。
  • Read committed:一个事务要等另一个事务提交完后才可以读取。会产生不可重复读。
  • Read committed:在开始读取数据时,不允许做修改操作。会产生幻读。
  • Serializable:操作会锁表,笔辩脏读幻读不可重复读。

Spring事务的传播特性

Spring中总共给出了7个传播特性。REQUIRED、SUPPORTS、MANDATORY、REQUIRES_NEW、NOT_SUPPORTED、NEVER、NESTED

@Transactional
public void a(){
    // 省略……
    b();
    // 省略……
}

@Transactional
public void b(){
    // 省略……
}

事务的传播特性解决的问题就是方法相互嵌套时的事务解决方式。当a方法调用b方法时,b方法出现了异常,b方法回滚,a方法是否需要回滚;如果a方法出现异常,a方法回滚,b方法是否需要回滚。

  • 不要事务
    • NEVER:如果都没有事务以非事务方式运行,有事务的话抛出异常。
    • NOT_SUPPORTED:如果没有事务以非事务方式运行,有事务的话将事务挂起。
  • 可有可无事务
    • SUPPORTS:如果没有事务以非事务方式运行,如果有就使用当前事务。
  • 必须有事务
    • REQUIRES_NEW:如果没有事务,就创建事务。如果有事务,将原来事务挂起,自己开启一个事务。
    • NESTED:如果没有事务,就创建一个事务。如果有就在当前事务嵌套事务。
    • REQUIRED:如果没有新建一个事务,如果有使用当前事务。
    • MANDATORY:如果没有抛出异常,如果右使用当前事务

Spring事务管理的原理

说起Spring的声明式事务时,提到注解一切可能都要从@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;
}

EnableTransactionManagement注解中引用了TransactionManagementConfigurationSelector类。

public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {

	@Override
	protected String[] selectImports(AdviceMode adviceMode) {
		switch (adviceMode) {
			case PROXY:
			    // 注册AutoProxyRegistrar和ProxyTransactionManagementConfiguration这两个类
				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);
	}

}

TransactionManagementConfigurationSelector这个类中的进行注册了AutoProxyRegistrar和ProxyTransactionManagementConfiguration这两个类。下面先进行看下ProxyTransactionManagementConfiguration这个类。

@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {

	@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	// 声明适配器
	public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
		BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
		// 设置@Transactional注解的解析属性
		advisor.setTransactionAttributeSource(transactionAttributeSource());
		// 设置advice方法拦截
		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() {
		TransactionInterceptor interceptor = new TransactionInterceptor();
		interceptor.setTransactionAttributeSource(transactionAttributeSource());
		if (this.txManager != null) {
			interceptor.setTransactionManager(this.txManager);
		}
		return interceptor;
	}

}

可以看到ProxyTransactionManagementConfiguration加了@Configuration注解,内部声明了一些Bean。注册了BeanFactoryTransactionAttributeSourceAdvisor、TransactionAttributeSource和TransactionInterceptor这几个类。在创建BeanFactoryTransactionAttributeSourceAdvisor时,Spring是将其直接进行new出来。

@SuppressWarnings("serial")
public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {

	@Nullable
	private TransactionAttributeSource transactionAttributeSource;

    // 切入点,方法匹配是否有@Transactional注解
	private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {
		@Override
		@Nullable
		protected TransactionAttributeSource getTransactionAttributeSource() {
			return transactionAttributeSource;
		}
	};

	public void setTransactionAttributeSource(TransactionAttributeSource transactionAttributeSource) {
		this.transactionAttributeSource = transactionAttributeSource;
	}

	public void setClassFilter(ClassFilter classFilter) {
		this.pointcut.setClassFilter(classFilter);
	}

	@Override
	public Pointcut getPointcut() {
		return this.pointcut;
	}

}

看完ProxyTransactionManagementConfiguration之后,接下来我们将看下AutoProxyRegistrar。

public class AutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

	private final Log logger = LogFactory.getLog(getClass());
	@Override
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		boolean candidateFound = false;
		Set<String> annTypes = importingClassMetadata.getAnnotationTypes();
		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;
				// 在这里注册了InfrastructureAdvisorAutoProxyCreator
				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));
		}
	}

}

InfrastructureAdvisorAutoProxyCreator的继承体系
image
InfrastructureAdvisorAutoProxyCreator是一个后置处理器,会在bean加载后检查是否要生成代理对象。

@SuppressWarnings("serial")
public class InfrastructureAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {

	@Nullable
	private ConfigurableListableBeanFactory beanFactory;


	@Override
	protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		super.initBeanFactory(beanFactory);
		this.beanFactory = beanFactory;
	}

	@Override
	protected boolean isEligibleAdvisorBean(String beanName) {
		return (this.beanFactory != null && this.beanFactory.containsBeanDefinition(beanName) &&
				this.beanFactory.getBeanDefinition(beanName).getRole() == BeanDefinition.ROLE_INFRASTRUCTURE);
	}

}

在这个类中基本上看不到什么处理方法,接着我们去看下父类AbstractAdvisorAutoProxyCreator的一些方法信息。


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

protected List<Advisor> findCandidateAdvisors() {
	Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
	// 返回所有增强器
	return this.advisorRetrievalHelper.findAdvisorBeans();
}

我们继续看下父类AbstractAutoProxyCreator中的一些方法

// 后置处理器
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;
}

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

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

	if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
		AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
	}

	ProxyFactory proxyFactory = new ProxyFactory();
	proxyFactory.copyFrom(this);

	if (!proxyFactory.isProxyTargetClass()) {
		if (shouldProxyTargetClass(beanClass, beanName)) {
			proxyFactory.setProxyTargetClass(true);
		}
		else {
			evaluateProxyInterfaces(beanClass, proxyFactory);
		}
	}

	Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
	proxyFactory.addAdvisors(advisors);
	proxyFactory.setTargetSource(targetSource);
	customizeProxyFactory(proxyFactory);

	proxyFactory.setFrozen(this.freezeProxy);
	if (advisorsPreFiltered()) {
		proxyFactory.setPreFiltered(true);
	}

	return proxyFactory.getProxy(getProxyClassLoader());
}

总结

  1. 通过@EnableTransactionManagement注解来进行注入
  2. EnableTransactionManagement注解中引入了TransactionManagementConfigurationSelector
  3. TransactionManagementConfigurationSelector进行注册AutoProxyRegistrar和ProxyTransactionManagementConfiguration
  4. ProxyTransactionManagementConfiguration类中进行声明了BeanFactoryTransactionAttributeSourceAdvisor(适配器)、TransactionAttributeSource(@Transactional注解解析器)、TransactionInterceptor(方法拦截器)。在适配器创建时又引入了TransactionAttributeSourcePointcut(切入点,方法匹配是否有@Transactional注解)
  5. AutoProxyRegistrar是一个ImportBeanDefinitionRegistrar的实现类,在后面帮我们注册InfrastructureAdvisorAutoProxyCreator。
  6. InfrastructureAdvisorAutoProxyCreator判断类是否需要代理,来帮我们进行代理类。