spring4.0事务超详细源码解析

事务

github:https://github.com/Notelzg/spring-reader
目前事务都是基于mysql的事务,其特性是 atomicity(原子性), consistency(一致性), isolation(隔离性), durability(持久性)
ACID四大特性。spring的事务就是在spring中对事务进行适配,通过模板的设计模式来避免 重复的代码,把重复性的开始事务、关闭事务、回滚等重复事情做了,而业务侧值只需要写业务代码
通过注解的方式开启事务就好了。这种方式提高了开发的效率,对事务进行代理对开发透明。 对后续的扩展比较方便。而且如果模板方法有问题,可以统一升级,而且避免了个人写事务导致的错误。
看到这里大家肯定会想到了spring的AOP,像这种重复的,有固定入口的,特别适合切面来做。spring 事务 也是实现了事务的切面增强,基于Spring AOP技术。

开启配置

在配置文件中,通过下面的配置开启对事务的支持。 这个如果你没有开启AOP的配置,这里会默认注册AOP,因为事务是基于AOP做的。

 //proxy-target-class 这里是tru,由于基于AOP所以这里指的是AOP的属性,是适应CgLib,还是JDK动态代理
 // 为true标识,代理类使用CgLib生成子类进行代理。如果Spring AOP还没有配置,这里会先注册AOP的 beanPost
 <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
  // 这里的false不会生效, 下面不会覆盖上面的(因为false不进行处理,true的时候属性设置为true,上面
  //这里是存在冲突的,请注意,可能导致事务失效,
 <aop:aspectj-autoproxy proxy-target-class="false"/>

配置激活的beanPost

1, xml命名空间和java类之间的映射 TxNamespaceHandler这个命名空间都是通过配置文件配置的, spring会加载所有的命名空间

spring-tx-4.3.30.RELEASE.jar/META-INF/spring.handlers
文件内容:
http\://www.springframework.org/schema/tx=org.springframework.transaction.config.TxNamespaceHandler

2, java事务命名空间解析

public class TxNamespaceHandler extends NamespaceHandlerSupport {
  static final String TRANSACTION_MANAGER_ATTRIBUTE = "transaction-manager";
  static final String DEFAULT_TRANSACTION_MANAGER_BEAN_NAME = "transactionManager";

  public void init() {
    this.registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser());
     // 上面配置的属性: annotation-driven  这个激活了这个配置
    this.registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
    this.registerBeanDefinitionParser("jta-transaction-manager", new JtaTransactionManagerBeanDefinitionParser());
  }

3, 注册事务需要用到的切面 AnnotationDrivenBeanDefinitionParser.java
xml文件解析, annotation-driven

public BeanDefinition parse(Element element, ParserContext parserContext) {
    this.registerTransactionalEventListenerFactory(parserContext);
    String mode = element.getAttribute("mode");
    // 这个应该是使用aspectJ的支持,目前我们都没有使用
    if ("aspectj".equals(mode)) {
    this.registerTransactionAspect(element, parserContext);
    } else {
    // 正常情况下都走的这里
    AnnotationDrivenBeanDefinitionParser.AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
}

注册 advice, pointCut, 织入 需要的类

// 专门定义了一个内部类来专门处理AOP相关的,也体现了设计模式的开闭原则
private static class AopAutoProxyConfigurer {
    private AopAutoProxyConfigurer() {
    }

    public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
      AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
      String txAdvisorBeanName = "org.springframework.transaction.config.internalTransactionAdvisor";
      if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) {
        // 对spring 事务注解进行解析, 获取方法/类上面的事务属性,在TransactionAttributeSourcePointcut的时候使用
        Object eleSource = parserContext.extractSource(element);
        RootBeanDefinition sourceDef = new RootBeanDefinition("org.springframework.transaction.annotation.AnnotationTransactionAttributeSource");
        sourceDef.setSource(eleSource);
        sourceDef.setRole(2);
        String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);
        
        // 事务增强器,实现了advice 
        RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class);
        interceptorDef.setSource(eleSource);
        interceptorDef.setRole(2);
        // 这里设置 transctionManager 类名称, 这里新增属性,key:transactionManagerBeanName, 
        //value: transactionManager(配置文件里面配置的,transaction-manager:)
        AnnotationDrivenBeanDefinitionParser.registerTransactionManager(element, interceptorDef);
        // 设置解析事务注解类,这里就可以看出把pointCut 和 事务解析 分离的好处了 
        interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
        String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);
        
        // advisor,里面包含了 advice 和 pointCut
        RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);
        advisorDef.setSource(eleSource);
        advisorDef.setRole(2);
        // 把事务解析器注入, 这里是RuntimeBeanReference类型, 初始化bean的时候就会去生成该bean的对象
        // 这里是因为该类在pointCut静态检查的时候就需要使用,所以先进行初始化
        advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
        // 把事务增强器注入, 这里是字符串类型,为什么呢,初始化bean的时候不会获取增强器的bean的对象?
        // 这里设置成string,是为了延迟初始化增强器,因为增强器是在生成具体的代理的时候才需要生成,并且使用,
        // 所以可以延迟加载生成对象,这里也符合spring的哲学,能延迟加载的就延迟加载
        // 这里设置拦截器的名称 ,然后通过 父类的getAdvice()方法去获取具体对象
        advisorDef.getPropertyValues().add("adviceBeanName", interceptorName);
        if (element.hasAttribute("order")) {
          advisorDef.getPropertyValues().add("order", element.getAttribute("order"));
        }
        parserContext.getRegistry().registerBeanDefinition(txAdvisorBeanName, advisorDef);
        CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource);
        compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName));
        compositeDef.addNestedComponent(new BeanComponentDefinition(interceptorDef, interceptorName));
        compositeDef.addNestedComponent(new BeanComponentDefinition(advisorDef, txAdvisorBeanName));
        parserContext.registerComponent(compositeDef);
      }

    }
  }

advisor

org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor
该类聚合了切点,和增强器,所以从这里开始分析,由于其实现了Advisor接口
所以BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans
所以BeanFactoryAdvisorRetrievalHelper是在AOP里面自动开启的,具体细节可以看AOP解析。
AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean 检查该类实现的所有接口,包含该类
检查所有方法,是否需要进行增强。
可以获取到事务的切面。

// 继承了 AbstractBeanFactoryPointcutAdvisor 有默认实现 getAdvice,只要设置adviceBeanName即可
// 在注册bena的时候,已经设置了adviceBeanName, 其类是:TransactionInterceptor.java
public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {

	private TransactionAttributeSource transactionAttributeSource;

    //切点,这个类是一个abstract, getTransactionAttributeSource 是子类实现,提供具体的解析,
    // TransactionAttributeSourcePointcut 提供整体的流程处理, 可以看做是一个模板类,处理统一的流程
	private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {
		@Override
		protected TransactionAttributeSource getTransactionAttributeSource() {
			return transactionAttributeSource;
		}
	};


	/**
	 * Set the transaction attribute source which is used to find transaction
	 * attributes. This should usually be identical to the source reference
	 * set on the transaction interceptor itself.
	 * @see TransactionInterceptor#setTransactionAttributeSource
	 */
	public void setTransactionAttributeSource(TransactionAttributeSource transactionAttributeSource) {
		this.transactionAttributeSource = transactionAttributeSource;
	}

	/**
	 * Set the {@link ClassFilter} to use for this pointcut.
	 * Default is {@link ClassFilter#TRUE}.
	 */
	public void setClassFilter(ClassFilter classFilter) {
		this.pointcut.setClassFilter(classFilter);
	}

    // 获取切点, 对类,方法
	@Override
	public Pointcut getPointcut() {
		return this.pointcut;
	}

}

切点

org.springframework.transaction.interceptor.TransactionAttributeSourcePointcut

abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {
    // 个人任务这里包装一层,把pointCut和 TransactionAttributeSource解析组合起来,方便后续的扩展, 同时也是
   // 降低了耦合度,复杂度,方便维护和扩展
	@Override
	public boolean matches(Method method, Class<?> targetClass) {
		if (targetClass != null && TransactionalProxy.class.isAssignableFrom(targetClass)) {
			return false;
		}
		// 子类实现该方法, 通过 AopAutoProxyConfigurer类,我们知道这里的source是
        // org.springframework.transaction.annotation.AnnotationTransactionAttributeSource
		TransactionAttributeSource tas = getTransactionAttributeSource();
		// 改属性正常情况下都不能为空,如果为空有问题了,事务属性解析不为空,则标识是事务,需要增强
		return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
	}
    // 子类实现这个方法,提供具体的注解解析实现,
	protected abstract TransactionAttributeSource getTransactionAttributeSource();

}

事务解析的整体流程

抽象父类,处理整理流程
Fallback 为什么有FallBack是因为解析属性的时候,会有很多倒退的操作
来保证能处理大部分的情况。

public abstract class AbstractFallbackTransactionAttributeSource implements TransactionAttributeSource {
    // 获取事务的属性
	@Override
	public TransactionAttribute getTransactionAttribute(Method method, Class<?> targetClass) {
	    // object类肯定不是,直接结束
		if (method.getDeclaringClass() == Object.class) {
			return null;
		}

		// First, see if we have a cached value.
		Object cacheKey = getCacheKey(method, targetClass);
		TransactionAttribute cached = this.attributeCache.get(cacheKey);
		if (cached != null) {
			// Value will either be canonical value indicating there is no transaction attribute,
			// or an actual transaction attribute.
			if (cached == NULL_TRANSACTION_ATTRIBUTE) {
				return null;
			}
			else {
				return cached;
			}
		}
		else {
			// 解析细节
			TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
			// Put it in the cache.
			if (txAttr == null) {
				this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);
			}
			else {
				String methodIdentification = ClassUtils.getQualifiedMethodName(method, targetClass);
				if (txAttr instanceof DefaultTransactionAttribute) {
					((DefaultTransactionAttribute) txAttr).setDescriptor(methodIdentification);
				}
				if (logger.isDebugEnabled()) {
					logger.debug("Adding transactional method '" + methodIdentification + "' with attribute: " + txAttr);
				}
				this.attributeCache.put(cacheKey, txAttr);
			}
			return txAttr;
		}
	}

	
	protected TransactionAttribute computeTransactionAttribute(Method method, Class<?> targetClass) {
		// 公共方法检查,非公共方法直接结束
		if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
			return null;
		}

        // 如果是cglib生成的代理,则获取其父类
		Class<?> userClass = ClassUtils.getUserClass(targetClass);
		// 如果method 是来自接口的,则返回 userClass中的method,返回实现类中的method
		Method specificMethod = ClassUtils.getMostSpecificMethod(method, userClass);
		// If we are dealing with method with generic parameters, find the original method.
		specificMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);

		// First try is the method in the target class.
		// 调用子类的具体实现,这里是子类进行扩展, 比如对TranactionL 注解的解析,如果方法上解析成功,直接返回
		TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
		if (txAttr != null) {
			return txAttr;
		}

		// Second try is the transaction attribute on the target class.
		// 方法上面没有,则进行类上面检查,同样是子类实现,比如注解解析
		txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
		if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
			return txAttr;
		}

        // 倒退操作,尽可能的把事务解析出来
		if (specificMethod != method) {
			// Fallback is to look at the original method.
			txAttr = findTransactionAttribute(method);
			if (txAttr != null) {
				return txAttr;
			}
			// Last fallback is the class of the original method.
			txAttr = findTransactionAttribute(method.getDeclaringClass());
			if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
				return txAttr;
			}
		}

		return null;
	}

	protected abstract TransactionAttribute findTransactionAttribute(Class<?> clazz);
	protected abstract TransactionAttribute findTransactionAttribute(Method method);
	protected boolean allowPublicMethodsOnly() { return false; }
}

事务注解解析入口

org.springframework.transaction.annotation.AnnotationTransactionAttributeSource
这里的具体解析是通过父类(AbstractFallbackTransactionAttributeSource)进行的,该类实现了父类的方法,进行扩展

// 注解解析类,继承一个抽象模板类,这个也是属于sprig的特色了,把统一处理的流程放在抽象类中,把经常变动/扩展的部分作为
// 抽象方法进行(封装变化), 达到开闭原则
public class AnnotationTransactionAttributeSource extends AbstractFallbackTransactionAttributeSource implements Serializable {
  // 只支持 public方法上面的 事务注解
  private final boolean publicMethodsOnly;
  // 注解解析类
  private final Set<TransactionAnnotationParser> annotationParsers;

  public AnnotationTransactionAttributeSource() {
    this(true);
  }

  public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {
    this.publicMethodsOnly = publicMethodsOnly;
    this.annotationParsers = new LinkedHashSet(4);
    // 默认支持 spring 事务解析, 目前事务注解都是走的这里
    this.annotationParsers.add(new SpringTransactionAnnotationParser());
  }

  protected TransactionAttribute findTransactionAttribute(Class<?> clazz) {
    return this.determineTransactionAttribute(clazz);
  }

  // 这两个方法 返回值、方法名称一样,入参不一样,属于静态的多态
  protected TransactionAttribute findTransactionAttribute(Method method) {
    return this.determineTransactionAttribute(method);
  }
  
  // 解析类、方法上面的注解
  protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
    if (element.getAnnotations().length > 0) {
      // 解析的类可能存在多个,所以是循环
      Iterator var2 = this.annotationParsers.iterator();

      while(var2.hasNext()) {
        TransactionAnnotationParser annotationParser = (TransactionAnnotationParser)var2.next();
        // 开始机械
        TransactionAttribute attr = annotationParser.parseTransactionAnnotation(element);
        // 解析就快速结束
        if (attr != null) {
          return attr;
        }
      }
    }

    return null;
  }

  protected boolean allowPublicMethodsOnly() {
    return this.publicMethodsOnly;
  }

}

事务注解解析器

一个接口,一个实现类,面向接口编程
比较符合先设计,再实现。spring这个模式非常的好。但是工作中有的时候很难做到
这种方法确实是和扩展。同时发现spring中类名起的都很好,形容词 名称 动词
每次自己起名字是真的难

public class SpringTransactionAnnotationParser implements TransactionAnnotationParser, Serializable {

	@Override
	public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
	   // 获取事务注解的所有属性
		AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(
				element, Transactional.class);
		// 解析		
		if (attributes != null) {
			return parseTransactionAnnotation(attributes);
		}
		else {
			return null;
		}
	}

    // 从这里就可以知道,spring 事务注解支持哪些配置
	protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) {
		RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();

        // 传播范围
		Propagation propagation = attributes.getEnum("propagation");
		rbta.setPropagationBehavior(propagation.value());
		// 隔离级别
		Isolation isolation = attributes.getEnum("isolation");
		rbta.setIsolationLevel(isolation.value());
		// 超时时间
		rbta.setTimeout(attributes.getNumber("timeout").intValue());
		// 只读
		rbta.setReadOnly(attributes.getBoolean("readOnly"));
		rbta.setQualifier(attributes.getString("value"));

		List<RollbackRuleAttribute> rollbackRules = new ArrayList<RollbackRuleAttribute>();
		// 什么异常进行回滚
		for (Class<?> rbRule : attributes.getClassArray("rollbackFor")) {
			rollbackRules.add(new RollbackRuleAttribute(rbRule));
		}
		// 什么类回滚
		for (String rbRule : attributes.getStringArray("rollbackForClassName")) {
			rollbackRules.add(new RollbackRuleAttribute(rbRule));
		}
		// 哪些类不需要回滚
		for (Class<?> rbRule : attributes.getClassArray("noRollbackFor")) {
			rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
		}
		// 哪些类名不需要回滚
		for (String rbRule : attributes.getStringArray("noRollbackForClassName")) {
			rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
		}
		rbta.setRollbackRules(rollbackRules);

		return rbta;
	}
}

增强器

package org.springframework.transaction.interceptor;
TransactionInterceptor.java
就是具体的事务增强器

增强器对象的获取


package org.springframework.aop.support;
public abstract class AbstractBeanFactoryPointcutAdvisor extends AbstractPointcutAdvisor implements BeanFactoryAware {

	private String adviceBeanName;

	// transient 序列化的时候,不进行序列化
    // volatile 关键字是可见性,不加可以吗?
    // 其实这里可以不加这关键字,因为单例本身是做了检查的,可以保证对象只创建一次, 加上就可以不用每次都走单例的流程,
    // 在这里就可以直接解决了,加快是了速度,所以这里加这个关键字主要是为了单例对象使用(大部分都是单例)
    // 而原始对象由于初始化的是有 synchronized关键字,所以可以保证其有序性、原子性
	private transient volatile Advice advice;
    // transient 序列化的时候,不进行序列化
    // 没有明白这里使用 volatile关键字的作用,由于这个对象会暴露出去,同时可以被重置,所以
    // 需要加上 volatile 关键字,保证其可见性
    private transient volatile Object adviceMonitor = new Object();

  // org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor
    // 继承了该类, 同时设置了adviceBeanName, TransactionInterceptor
	public void setAdviceBeanName(String adviceBeanName) {
		this.adviceBeanName = adviceBeanName;
	}

	@Override
	public Advice getAdvice() {
	    // 单例,已经实例化的直接返回
		Advice advice = this.advice;
		if (advice != null || this.adviceBeanName == null) {
			return advice;
		}

		Assert.state(this.beanFactory != null, "BeanFactory must be set to resolve 'adviceBeanName'");
		if (this.beanFactory.isSingleton(this.adviceBeanName)) {
			// 直接通过容器初始化增强器,由于增强器beanDefinition 在xml解析阶段已经注册,所以这里通过beanName可以完成bean的对象的
            // 初始化
			advice = this.beanFactory.getBean(this.adviceBeanName, Advice.class);
			this.advice = advice;
			return advice;
		}
		
		else {
			// No singleton guarantees from the factory -> let's lock locally but
			// reuse the factory's singleton lock, just in case a lazy dependency
			// of our advice bean happens to trigger the singleton lock implicitly...
          // 对于非单利的,也要进行单利处理,springAOP只能使用单利,因为如果使用非单例,将会生成n个对象
          // 对内存造成非常大的浪费,如果有1000个类,则要生成1000个对象,完成没有必要,所以切面本身要线程
          // 安全,因为切面通过锁巧妙的实现了单例
          synchronized (this.adviceMonitor) {
				if (this.advice == null) {
					this.advice = this.beanFactory.getBean(this.adviceBeanName, Advice.class);
				}
				return this.advice;
			}
		}
	}
}

增强器对象的具体实现细节

这里是

public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {

	public TransactionInterceptor() {
	}

	@Override
	public Object invoke(final MethodInvocation invocation) throws Throwable {
		// Work out the target class: may be {@code null}.
		// The TransactionAttributeSource should be passed the target class
		// as well as the method, which may be from an interface.
		Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);

		// 调用父类的方法, 通过回调方法,进行扩展
		return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
			@Override
			public Object proceedWithInvocation() throws Throwable {
				return invocation.proceed();
			}
		});
	}
}

事务操作整体流程

public abstract class TransactionAspectSupport implements BeanFactoryAware, InitializingBean {
	/**
	 * Key to use to store the default transaction manager.
	 */
	private static final Object DEFAULT_TRANSACTION_MANAGER_KEY = new Object();

	// 事务信息,放到这里,进行方法调用的时候进行传播
	private static final ThreadLocal<TransactionInfo> transactionInfoHolder =
			new NamedThreadLocal<TransactionInfo>("Current aspect-driven transaction");

	// bean的两个属性,bean初始化的时候必须设置,否则会报错,后面会检查
	private PlatformTransactionManager transactionManager;
	private TransactionAttributeSource transactionAttributeSource;

	// spring 事务处理的主流程
	protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation)
			throws Throwable {

        // 解析事务属性
		final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
		// 获取事务管理器,根据配置文件中配置的事务管理beanId, 从spring容器中生成事务管理器bean(bean也在配置文件中配置了) 
		final PlatformTransactionManager tm = determineTransactionManager(txAttr);
		// 增强方法标识, com.lzg.note.aop.TestA.insert(包名+类名+方法名)
		final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
		// true 走这里 
		if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
			// Standard transaction demarcation with getTransaction and commit/rollback calls.
            // 生成事务如果需要的,根据事务的传播行为
			TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
			Object retVal;
			try {
                // 回调处理,继续走其他的切面增强,和目标方法
				retVal = invocation.proceedWithInvocation();
			}
			catch (Throwable ex) {
				// target invocation exception
				completeTransactionAfterThrowing(txInfo, ex);
				throw ex;
			}
			finally {
			    // 清除事务相关的数据, 主要是thradLocal中的,同时会恢复之前被挂起的事务(如果之前有挂起的事务的话)
				cleanupTransactionInfo(txInfo);
			}
			// 目标方法处理完成,处理完成,事务提交,或者回滚, 最后会进行 resume, 如果之前进行过suspend操作的话
			commitTransactionAfterReturning(txInfo);
			return retVal;
		} else {// 非核心代码删除 }
	}

	/**
	 * 获取事务管理器,根据配置
	 */
	protected PlatformTransactionManager determineTransactionManager(TransactionAttribute txAttr){
        // Do not attempt to lookup tx manager if no tx attributes are set
        if (txAttr == null || this.beanFactory == null) {
          return getTransactionManager();
        }

        String qualifier = txAttr.getQualifier();
        if (StringUtils.hasText(qualifier)) {
          return determineQualifiedTransactionManager(qualifier);
        }
        // 解析配置文件的时候已经设置了 
        else if (StringUtils.hasText(this.transactionManagerBeanName)) {
          return determineQualifiedTransactionManager(this.transactionManagerBeanName);
        } else { //删除非核心代码 }
        }
        private PlatformTransactionManager determineQualifiedTransactionManager (String qualifier){
          PlatformTransactionManager txManager = this.transactionManagerCache.get(qualifier);
          if (txManager == null) {
            // 从容器中获取
            txManager = BeanFactoryAnnotationUtils.qualifiedBeanOfType(
                    this.beanFactory, PlatformTransactionManager.class, qualifier);
            this.transactionManagerCache.putIfAbsent(qualifier, txManager);
          }
          return txManager;
        }

        // 根据传播机制,进行生成/取出/挂起已有的事务	
        protected TransactionInfo createTransactionIfNecessary (
                PlatformTransactionManager tm, TransactionAttribute txAttr,
        final String joinpointIdentification){

          TransactionStatus status = null;
          if (txAttr != null) {
            if (tm != null) {
              // 根据传播机制,进行生成/取出/挂起已有的事务
              status = tm.getTransaction(txAttr);
            }
          }
          // 包装事务状态到事务信息中, txInfo
          return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
        }

        protected TransactionInfo prepareTransactionInfo (PlatformTransactionManager tm,
                TransactionAttribute txAttr, String joinpointIdentification, TransactionStatus
        status){

          TransactionInfo txInfo = new TransactionInfo(tm, txAttr, joinpointIdentification);
          // The transaction manager will flag an error if an incompatible tx already exists.
          txInfo.newTransactionStatus(status);
          // 设置到threadLocal, 同时如果已经有txInfo存在,则把上一个保存到oldTxInfo字段中,后续resumer的时候会用到
          txInfo.bindToThread();
          return txInfo;
        }

        /**
         * Execute after successful completion of call, but not after an exception was handled.
         * Do nothing if we didn't create a transaction.
         * @param txInfo information about the current transaction
         */
        protected void commitTransactionAfterReturning (TransactionInfo txInfo){
          if (txInfo != null && txInfo.hasTransaction()) {
            txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
          }
        }

        /**
         * Handle a throwable, completing the transaction.
         * We may commit or roll back, depending on the configuration.
         * @param txInfo information about the current transaction
         * @param ex throwable encountered
         */
        protected void completeTransactionAfterThrowing (TransactionInfo txInfo, Throwable ex){
          if (txInfo != null && txInfo.hasTransaction()) {
            if (logger.isTraceEnabled()) {
              logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() +
                      "] after exception: " + ex);
            }
            if (txInfo.transactionAttribute.rollbackOn(ex)) {
              try {
                txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
              } catch (TransactionSystemException ex2) {
                logger.error("Application exception overridden by rollback exception", ex);
                ex2.initApplicationException(ex);
                throw ex2;
              } catch (RuntimeException ex2) {
                logger.error("Application exception overridden by rollback exception", ex);
                throw ex2;
              } catch (Error err) {
                logger.error("Application exception overridden by rollback error", ex);
                throw err;
              }
            } else {
              // We don't roll back on this exception.
              // Will still roll back if TransactionStatus.isRollbackOnly() is true.
              try {
                txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
              } catch (TransactionSystemException ex2) {
                logger.error("Application exception overridden by commit exception", ex);
                ex2.initApplicationException(ex);
                throw ex2;
              } catch (RuntimeException ex2) {
                logger.error("Application exception overridden by commit exception", ex);
                throw ex2;
              } catch (Error err) {
                logger.error("Application exception overridden by commit error", ex);
                throw err;
              }
            }
          }
        }

        protected void cleanupTransactionInfo (TransactionInfo txInfo){
          if (txInfo != null) {
            txInfo.restoreThreadLocalStatus();
          }
        }

        protected final class TransactionInfo {
          private void bindToThread() {
            this.oldTransactionInfo = transactionInfoHolder.get();
            transactionInfoHolder.set(this);
          }

          private void restoreThreadLocalStatus() {
            transactionInfoHolder.set(this.oldTransactionInfo);
          }
        }
}

事务管理器抽象类处理主流程

org.springframework.transaction.support.AbstractPlatformTransactionManager

public abstract class AbstractPlatformTransactionManager implements PlatformTransactionManager, Serializable {

  // 获取事务
  public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
    // 具体获取事务,由子类实现,DataSourceTransactionManager, 该类是spring-jdbc中去做,是另外一个jar包,定义和实现分离
    // 如果当前线程的ThradLcoal中已经存在一个,则这里拿到的是已有的连接
    Object transaction = doGetTransaction();

    // 如果当前事务,是之前创建的,就根据传播机制进行重新生成、挂起,等操作
    // 不管是什么传播机制,除了需要抛出异常的情况,其他情况都会重新生成一个新的TransactionStatus
    // 但是 transaction可能一样,如果是都 PROPAGATION_REQUIRE
    // 这个是因为每个@Transactionl 注解的属性可能不一样,但是其数据库连接是复用的(如果不需要生成新的事务的情况下)
    // 我们都知道数据库连接资源是有限的,所以在一个事务中,应该尽可能使用同一个事务连接,非不要不要创建新的
    if (isExistingTransaction(transaction)) {
      return handleExistingTransaction(definition, transaction, debugEnabled);
    }
    // 当前没有事务存在, 抛出异常,如果有事务在上一步返回
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
      throw new IllegalTransactionStateException(
              "No existing transaction found for transaction marked with propagation 'mandatory'");
    } else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
            definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
            definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
      SuspendedResourcesHolder suspendedResources = suspend(null);
      try {
        boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
        DefaultTransactionStatus status = newTransactionStatus(
                definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
        // 开始事务, 获取数据库连接的连接,设置超时时间,隔离级别等事务的准备工作
        doBegin(transaction, definition);
        // 把当前事务设置threadLocal中,后续使用,主要是为了线程内的同步(一个事务跨越了多个线程帧栈)
        prepareSynchronization(status, definition);
        return status;
      } catch (RuntimeException ex) {
        resume(null, suspendedResources);
        throw ex;
      } catch (Error err) {
        resume(null, suspendedResources);
        throw err;
      }
    }
  }

  // 把当前事务信息,设置到threLocal里面,为了后续同步控制使用
  protected void prepareSynchronization(DefaultTransactionStatus status, TransactionDefinition definition) {
    if (status.isNewSynchronization()) {
      TransactionSynchronizationManager.setActualTransactionActive(status.hasTransaction());
      TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(
              definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT ?
                      definition.getIsolationLevel() : null);
      TransactionSynchronizationManager.setCurrentTransactionReadOnly(definition.isReadOnly());
      TransactionSynchronizationManager.setCurrentTransactionName(definition.getName());
      TransactionSynchronizationManager.initSynchronization();
    }
  }

  // 传播机制的设置
  private TransactionStatus handleExistingTransaction(
          TransactionDefinition definition, Object transaction, boolean debugEnabled)
          throws TransactionException {

    // 不需要事务,则抛出异常
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
      throw new IllegalTransactionStateException(
              "Existing transaction found for transaction marked with propagation 'never'");
    }

    // 不支持事务,则挂起当前事务
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
      // 挂起事务,把旧事务信息保存到  suspendedResources, 每个事务状态中会保存上一个挂起的事务,resume 的时候进行恢复
      // 通过保存前一个事务的方式,把多个事务链接起来,形成一个链表
      // 把当前的dataSrouce 和 数据库连接,从threadLocal中去掉,解除绑定
      Object suspendedResources = suspend(transaction);
      boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
      // 事务设置为空
      return prepareTransactionStatus(
              definition, null, false, newSynchronization, debugEnabled, suspendedResources);
    }
    // 需要重新生成事务
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
      SuspendedResourcesHolder suspendedResources = suspend(transaction);
      try {
        boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
        DefaultTransactionStatus status = newTransactionStatus(
                definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
        // 重新开启事务, 创建新的数据库连接,数据库连接资源有限,所以尽可能少的创建新的连接
        doBegin(transaction, definition);
        prepareSynchronization(status, definition);
        return status;
      } catch (RuntimeException beginEx) {
        // 遇到异常,会进行回滚
        resumeAfterBeginException(transaction, suspendedResources, beginEx);
        throw beginEx;
      } catch (Error beginErr) {
        resumeAfterBeginException(transaction, suspendedResources, beginErr);
        throw beginErr;
      }
    }

    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
      // 使用savePoint的话,保存一个savePoint,复用已有的事务,
      // 这里这样做的目的是为了减少资源的消费,因为数据库连接资源是有限的,宝贵的
      // DataSourceTransactionManager 默认是打开的,所以走的是这里 
      if (useSavepointForNestedTransaction()) {
        // Create savepoint within existing Spring-managed transaction,
        // through the SavepointManager API implemented by TransactionStatus.
        // Usually uses JDBC 3.0 savepoints. Never activates Spring synchronization.
        DefaultTransactionStatus status =
                prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);
        status.createAndHoldSavepoint();
        return status;
      } else {
        // 生成一个新的事务
        // Nested transaction through nested begin and commit/rollback calls.
        // Usually only for JTA: Spring synchronization might get activated here
        // in case of a pre-existing JTA transaction.
        boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
        DefaultTransactionStatus status = newTransactionStatus(
                definition, transaction, true, newSynchronization, debugEnabled, null);
        doBegin(transaction, definition);
        prepareSynchronization(status, definition);
        return status;
      }
    }
    // 除了需要特别处理的(生成新的事务,抛出异常,savePoint), 其他情况都走这里,使用已有的事务
    // 使用已有事务就意味着,复用旧事务的超时时间,隔离级别, 回滚配置,注意可能导致事务注解失效
    boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
    return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);
  }

  // 生成一个新的status,但是事务还是使用之前的
  protected final DefaultTransactionStatus prepareTransactionStatus(
          TransactionDefinition definition, Object transaction, boolean newTransaction,
          boolean newSynchronization, boolean debug, Object suspendedResources) {

    DefaultTransactionStatus status = newTransactionStatus(
            definition, transaction, newTransaction, newSynchronization, debug, suspendedResources);
    prepareSynchronization(status, definition);
    return status;
  }
  
  // 挂起当前事务, 返回上一个事务的数据,恢复事务的时候使用
  protected final SuspendedResourcesHolder suspend(Object transaction) throws TransactionException {
    if (TransactionSynchronizationManager.isSynchronizationActive()) {
      // 对于已经执行的事务语句,进行挂起操作,主要是释放资源 sqlSessionFactory 和sql语句相关的资源
      // 比如使用 mybatis 生成的mapper接口,就是使用的是 sqlSession
      List<TransactionSynchronization> suspendedSynchronizations = doSuspendSynchronization();
      try {
        Object suspendedResources = null;
        if (transaction != null) {
          // 解除资源绑定,数据库连接 从threadLocal 中, 子类,DataSourceTransactionManager  实现
          suspendedResources = doSuspend(transaction);
        }
        String name = TransactionSynchronizationManager.getCurrentTransactionName();
        TransactionSynchronizationManager.setCurrentTransactionName(null);
        boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();
        TransactionSynchronizationManager.setCurrentTransactionReadOnly(false);
        Integer isolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
        TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(null);
        boolean wasActive = TransactionSynchronizationManager.isActualTransactionActive();
        TransactionSynchronizationManager.setActualTransactionActive(false);
        // 需要保存上一个数据库连接,用来恢复事务
        return new SuspendedResourcesHolder(
                suspendedResources, suspendedSynchronizations, name, readOnly, isolationLevel, wasActive);
      }
      catch (RuntimeException ex) {
        // doSuspend failed - original transaction is still active...
        doResumeSynchronization(suspendedSynchronizations);
        throw ex;
      }
      catch (Error err) {
        // doSuspend failed - original transaction is still active...
        doResumeSynchronization(suspendedSynchronizations);
        throw err;
      }
    }
    else if (transaction != null) {
      // Transaction active but no synchronization active.
      Object suspendedResources = doSuspend(transaction);
      return new SuspendedResourcesHolder(suspendedResources);
    }
    else {
      // Neither transaction nor synchronization active.
      return null;
    }
  }

  protected final void resume(Object transaction, SuspendedResourcesHolder resourcesHolder)
          throws TransactionException {

    if (resourcesHolder != null) {
      Object suspendedResources = resourcesHolder.suspendedResources;
      if (suspendedResources != null) {
        // 子类实现,把数据库连接重新设置到threadLocal中
        doResume(transaction, suspendedResources);
      }
      List<TransactionSynchronization> suspendedSynchronizations = resourcesHolder.suspendedSynchronizations;
      if (suspendedSynchronizations != null) {
        TransactionSynchronizationManager.setActualTransactionActive(resourcesHolder.wasActive);
        TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(resourcesHolder.isolationLevel);
        TransactionSynchronizationManager.setCurrentTransactionReadOnly(resourcesHolder.readOnly);
        TransactionSynchronizationManager.setCurrentTransactionName(resourcesHolder.name);
        // 恢复sqlSessoionFactory 相关
        doResumeSynchronization(suspendedSynchronizations);
      }
    }
  }

  @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()) {
      processRollback(defStatus);
      return;
    }
    if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
      processRollback(defStatus);
      if (status.isNewTransaction() || isFailEarlyOnGlobalRollbackOnly()) {
        throw new UnexpectedRollbackException(
                "Transaction rolled back because it has been marked as rollback-only");
      }
      return;
    }

    processCommit(defStatus);
  }

  private void processCommit(DefaultTransactionStatus status) throws TransactionException {
    try {
      boolean beforeCompletionInvoked = false;
      try {
        prepareForCommit(status);
        triggerBeforeCommit(status);
        triggerBeforeCompletion(status);
        beforeCompletionInvoked = true;
        boolean globalRollbackOnly = false;
        if (status.hasSavepoint()) {
          status.releaseHeldSavepoint();
        }
        else if (status.isNewTransaction()) {
          // 如果不是一个新的事务,则不进行提交, 对于 @Transactionl 注解同时嵌套调用的情况,
          // 开始 methdA->methodB 结束 的两个方法都有Transactionl注解,
          // methodB处理完之后,是不会调用这里的,只有methodA处理完走到这里的时候才进行调用
          // 只会线程栈帧 从methodB, 回到methodA,并且走到这里的时候才行
          // 想一下,如果 methodB 如果执行了commit的话,事务就结束了
          doCommit(status);
        }
      }
      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 ex) {
        if (!beforeCompletionInvoked) {
          triggerBeforeCompletion(status);
        }
        doRollbackOnCommitException(status, ex);
        throw ex;
      }
      catch (Error err) {
        if (!beforeCompletionInvoked) {
          triggerBeforeCompletion(status);
        }
        doRollbackOnCommitException(status, err);
        throw err;
      }

      // 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 {
      // 清除当前数据,同时如果还有父事务,则进行事务的恢复 ,resumer
      cleanupAfterCompletion(status);
    }
  }

  private void cleanupAfterCompletion(DefaultTransactionStatus status) {
    status.setCompleted();
    if (status.isNewSynchronization()) {
      // 清理事务管理器
      TransactionSynchronizationManager.clear();
    }
    if (status.isNewTransaction()) {
      //只有最初生成数据库连接的事务结束, 才能清理数据库连接,释放数据库资源, 
      doCleanupAfterCompletion(status.getTransaction());
    }
    if (status.getSuspendedResources() != null) {
      // 恢复之前挂起的事务,让上一个事务继续运行
      resume(status.getTransaction(), (SuspendedResourcesHolder) status.getSuspendedResources());
    }
  }

}


spring-jdbc 事务管理器具体细节实现

处理数据库连接的创建,释放,开始,提交,回滚,恢复等细节
org.springframework.jdbc.datasource.DataSourceTransactionManager
spring-jdbc jar包

/**
 * <!--  事务管理器, 这里的名称,要和上面 tx 事务里面 transaction-manager 属性里面配置的一样,否则无法找到 -->
 * <bean id="transactionManager"
 * class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
 * <property name="dataSource" ref="adminDataSource"/>
 * </bean> 
 * 配置了数据原
 */
public class DataSourceTransactionManager extends AbstractPlatformTransactionManager
        implements ResourceTransactionManager, InitializingBean {

  private DataSource dataSource;
  
  // 获取一个事务
  @Override
  protected Object doGetTransaction() {
    DataSourceTransactionObject txObject = new DataSourceTransactionObject();
    txObject.setSavepointAllowed(isNestedTransactionAllowed());
    // 第一次这里返回null, 从当前threadLocal里面取出,一个连接,key 是dataSource
    // 事务是每个线程只能有一个连接,如果有多个连接就无法知道当前事务用的是哪个连接,就乱掉了
    // 如果当前存在连接,则直接返回
    ConnectionHolder conHolder =
            (ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource);
    txObject.setConnectionHolder(conHolder, false);
    return txObject;
  }
  
  // 开始事务
  @Override
  protected void doBegin(Object transaction, TransactionDefinition definition) {
    DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
    Connection con = null;

    try {
      // 第一次走这里,因为是空的
      if (!txObject.hasConnectionHolder() ||
              txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
        // 通过dataSource 数据源生成一个连接,数据源一般都是一个连接池
        Connection newCon = this.dataSource.getConnection();
        // 第一次生成连接,所以设置为true,标识最开始
        txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
      }

      txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
      con = txObject.getConnectionHolder().getConnection();

      // 设置 readOnly ,和 事务的隔离级别,如果当前配置的不是默认值的话
      Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
      txObject.setPreviousIsolationLevel(previousIsolationLevel);

      // 关闭事务自动提交,改为手动提交, 因为默认获取数据库连接的时候,事务已经开启了,所以这里关闭
      // 事务提交,就标识接下里的数据库操作都是同一个事务中, 在提交之前,所以只有新的连接处理完成之后
      // 才会调用commit接口,如果每次都调用commit就有问题了
      if (con.getAutoCommit()) {
        txObject.setMustRestoreAutoCommit(true);
        con.setAutoCommit(false);
      }

      // 准备工作
      prepareTransactionalConnection(con, definition);
      // 激活事务,事务已经准备好了
      txObject.getConnectionHolder().setTransactionActive(true);

      int timeout = determineTimeout(definition);
      if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
        txObject.getConnectionHolder().setTimeoutInSeconds(timeout);
      }

      // 刚创建的新连接,需要把数据源和连接绑定一下
      if (txObject.isNewConnectionHolder()) {
        TransactionSynchronizationManager.bindResource(getDataSource(), txObject.getConnectionHolder());
      }
    }

    catch (Throwable ex) {
      if (txObject.isNewConnectionHolder()) {
        DataSourceUtils.releaseConnection(con, this.dataSource);
        txObject.setConnectionHolder(null, false);
      }
      throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);
    }
  }

  @Override
  protected Object doSuspend(Object transaction) {
    DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
    txObject.setConnectionHolder(null);
    return TransactionSynchronizationManager.unbindResource(this.dataSource);
  }

  @Override
  protected void doResume(Object transaction, Object suspendedResources) {
    TransactionSynchronizationManager.bindResource(this.dataSource, suspendedResources);
  }

  @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 new TransactionSystemException("Could not commit JDBC transaction", ex);
    }
  }

  @Override
  protected void doRollback(DefaultTransactionStatus status) {
    DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
    Connection con = txObject.getConnectionHolder().getConnection();
    if (status.isDebug()) {
      logger.debug("Rolling back JDBC transaction on Connection [" + con + "]");
    }
    try {
      con.rollback();
    }
    catch (SQLException ex) {
      throw new TransactionSystemException("Could not roll back JDBC transaction", ex);
    }
  }
}

事务同步机制管理

org.springframework.transaction.support.TransactionSynchronizationManager
把数据库连接放入到threadLocal中,进行保存,方便在方法调用中进行使用
mybatis等都需要使用
spring-tx jar包

// 事务同步机制管理器,主要管理数据库连接,以及mybatis这种sqlSession的管理
public class TransactionSynchronizationManager {
  public static Object getResource(Object key) {
    // 针对代理,回去目标对象
    Object actualKey = TransactionSynchronizationUtils.unwrapResourceIfNecessary(key);
    Object value = doGetResource(actualKey);
    return value;
  }

  /**
   * Actually check the value of the resource that is bound for the given key.
   */
  private static Object doGetResource(Object actualKey) {
    Map<Object, Object> map = resources.get();
    // 第一次获取的是空的
    if (map == null) {
      return null;
    }
    Object value = map.get(actualKey);
    // Transparently remove ResourceHolder that was marked as void...
    if (value instanceof ResourceHolder && ((ResourceHolder) value).isVoid()) {
      map.remove(actualKey);
      // Remove entire ThreadLocal if empty...
      if (map.isEmpty()) {
        resources.remove();
      }
      value = null;
    }
    return value;
  }

  // 把数据连接 和 数据dataSrouce 进行绑定,开始事务的时候需要做,方便后续事务获取,复用已有的事务
  public static void bindResource(Object key, Object value) throws IllegalStateException {
    Object actualKey = TransactionSynchronizationUtils.unwrapResourceIfNecessary(key);
    Assert.notNull(value, "Value must not be null");
    Map<Object, Object> map = resources.get();
    // set ThreadLocal Map if none found
    if (map == null) {
      map = new HashMap<Object, Object>();
      resources.set(map);
    }
    Object oldValue = map.put(actualKey, value);
    // Transparently suppress a ResourceHolder that was marked as void...
    if (oldValue instanceof ResourceHolder && ((ResourceHolder) oldValue).isVoid()) {
      oldValue = null;
    }
    // 正常情况下,只有新生成的事务才需要绑定,复用的不需要绑定
    if (oldValue != null) {
      throw new IllegalStateException("Already value [" + oldValue + "] for key [" +
              actualKey + "] bound to thread [" + Thread.currentThread().getName() + "]");
    }
  }

  // 解除资源帮定,当事务结束,或者需要挂起事务的时候 
  public static Object unbindResource(Object key) throws IllegalStateException {
    Object actualKey = TransactionSynchronizationUtils.unwrapResourceIfNecessary(key);
    Object value = doUnbindResource(actualKey);
    if (value == null) {
      throw new IllegalStateException(
              "No value for key [" + actualKey + "] bound to thread [" + Thread.currentThread().getName() + "]");
    }
    return value;
  }
}

织入

通过springAOP技术实现,事务增强器作为springAOP增强器链中的一个元素,进行增强。
这里就不再详细讲了,主要就是把利用aop机制,根据advisor,匹配之后把
TransactionInterceptor 作为其增强链中的一环,具体可以看
spring-aop这篇文章。这里只记录 transactionAdvisor如何注册
advice TransactionInterceptor 如何进行增强的细节,aop看另外的文章。

事务传播机制

getTransaction()方法里面写的比较清楚,可以再看下代码
事务传播机制在这个类里面有详细的介绍,想看原理,可以看
上面该类的源码解析
AbstractPlatformTransactionManager.getTransaction()

public interface TransactionDefinition {

	/**
	 * Support a current transaction; create a new one if none exists.
	 *  如果当前没有事务,则生成一个事务。如果有则复用已有的事务
	 *   要注意的就是,既然是复用已有的事务,那肯定是要复用已有事务的配置,比如超时时间,回滚,不回滚
	 *   这些事务配置,如果你的事务有特殊配置,就应该使用 PROPAGATION_REQUIRED_NEW
	 *    重新生成一个事务, 如果没有特殊配置则不需要
	 ** /
	int PROPAGATION_REQUIRED = 0;

	/**
	 * Support a current transaction; execute non-transactionally if none exists.
	 * 当前已经存在事务,则使用已有的,否则也不会新建事务
	 */
	int PROPAGATION_SUPPORTS = 1;

	/**
	 * Support a current transaction; throw an exception if no current transaction
	 * exists. 
	 * 当前必须要有事务,否则会抛出异常, 有一些事务要求自己处于另外一个事务当中,不能单独存在,使用这种
	 * 比如参加活动,新增活动记录、增加积分。假如拆成了两个本地事务,则后面的一定要和前面的事务处于同一个
	 * 事务当中,否则可能会导致数据的不一致。对于同时操作多个本地数据库的,但是处于不同的方法中的时候,就
	 * 需要这个类型
	 * AbstractPlatformTransactionManager.getTransaction() 有详细的说明,可以下上面
	int PROPAGATION_MANDATORY = 2;

	/**
	 * Create a new transaction, suspending the current transaction if one exists.
	 * 如果当前没有事务则创建一个新的事务,如果当前已经有事务了,则挂起当前的事务。
	 * 如果两个事务的配置不一样,有特殊配置的事务,这种就需要
	 */
	int PROPAGATION_REQUIRES_NEW = 3;

	/**
	 * Do not support a current transaction; rather always execute non-transactionally.
	 * 如果当前已经存在事务则挂起当前事务,如果没有也不会新建
	 * JtaTransactionManage 特有的
	 */
	int PROPAGATION_NOT_SUPPORTED = 4;

	/**
	 * Do not support a current transaction; throw an exception if a current transaction
     * 不支持事务,如果有事务则抛出异常	
	 */
	int PROPAGATION_NEVER = 5;

	/**
	 * Execute within a nested transaction if a current transaction exists,
     * 执行一个嵌套的事务,目前已有的 DataSourceTransactionMangeer	
     * 默认使用 savePoint 进行支持,除非手动关闭这个配置,
     * 使用 savePoint 达成一样的效果,还可以节省宝贵的数据库连接资源
     * 当一些事务失败,可以忽略的时候,可以使用这个注解
     * 把一些不重要的处理,从大的事务中拆出来,放到单独的事务中,进行处理
     * 也是为了保证事务的柔性吧,即使一些失败了,也可以接受,只要核心事务没问题就行
	 */
	int PROPAGATION_NESTED = 6;
	}

事务失效的原因

1, aop失效的时候,事务肯定是失效的,
比如非公共方法,内部调用, 这个是由于aop代理机制的问题导致的
非公共方法不会被代理
内部调用的对象使用的非代理对象,如果内部调用需要使用代理对象,需要特殊处理才行
2, 回滚类特殊设置和最初开始事务的时候设置的不一样,导致回滚失效了
或者配置不生效
3, aop的配置
proxy-target-class=“true”
属性的配置为true,使用cglib代码,生成是子类,继承当前类,这种模式
可以使用当前类的类型,从spring容器中获取生成的代理对象,或者进行注入。
但是对于 false的,使用 JdkDynamicAopProxy
生成的代理对象,和原来的类没有关系,只能使用类实现的接口进行获取,并且
只能使用接口方法。
所以如果是非接口的事务方法,必须使用true,比较稳妥

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值