spring 事务 XML

事务就是AOP的很典型的应用。(原来需要自己写代码前开启关闭事务,现在通过spring的配置)

所以必要要有<aop:config>,<aop:config>里面要有<aop:pointcut>,<aop:pointcut>就是拦截的表达式(匹配哪些方法要拦截),还要有<aop:advisor>这是切面,切面里面要有pointcut-ref, advice-ref。advice-ref是一个增强,这个增强在事务里面就是对拦截的方法进行开始关闭事务(AOP的增强就是执行before,after,around方法)就是前置后置增强,

事务的开启关闭挂起,都是通过JDBC的事务开启关闭嵌套实现的。
public interface AA {
    public void purchase(int isbn) ;
}
public class BookShopXMLService implements AA{
    @Autowired
    private JdbcTemplate jdbcTemplate;
    public JdbcTemplate getJdbcTemplate() {
        return jdbcTemplate;
    }
    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }
    public void purchase(int isbn) {
        jdbcTemplate.update("update aa set name='5' where id=?", isbn);
            //        int x = 1/0;
        jdbcTemplate.update("update aa set name='6' where id=?", isbn);
    }
}
public class Test2 {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath*:config" + "/spring/applicationContext-core.xml");
        AA as = (AA) context.getBean("bookShopXMLService");
        as.purchase(1);
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
    
    <!-- 导入外部属性文件 -->
    <context:property-placeholder location="classpath*:config/core/core.properties" />
    
    <!-- 数据库连接池 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driver}"></property>
        <property name="jdbcUrl" value="${jdbc.url}"></property>
        <property name="user" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>
    
    <!-- 配置jdbcTemplate -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    
    <bean id="bookShopXMLService" class="cn.sdut.xml.BookShopXMLService">
        <property name="jdbcTemplate" ref="jdbcTemplate"></property>
    </bean>
    
    <!-- 配置事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!-- 配置事务通知 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <!-- 配置要添加事务的方法 -->
        <tx:attributes>
            <!-- 给purchase方法添加事务 -->
            <tx:method name="purchase" propagation="REQUIRED" isolation="READ_COMMITTED" />
        </tx:attributes>
    </tx:advice>
    
    <!-- 配置AOP -->
    <aop:config proxy-target-class="false">
        <!-- 配置切入点表达式 -->
        <aop:pointcut expression="execution(* cn.sdut.xml.BookShopXMLService.*(..))" id="pointcut" />
        <!-- 将事务通知和切入点表达式关联起来 -->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut" />
    </aop:config>
    
</beans>
<tx:advice id="userTxAdvice" transaction-manager="transactionManager">     增强
        <tx:attributes>
             <tx:method name="save*" propagation="REQUIRED" read-only="false"
                       rollback-for="java.lang.RuntimeException" isolation="DEFAULT"/> 
            <tx:method name="saveTest" propagation="REQUIRED" read-only="false"
                       rollback-for="java.lang.RuntimeException" isolation="DEFAULT"/>
            <tx:method name="saveTest1" propagation="NESTED" read-only="false"
                       rollback-for="java.lang.RuntimeException" isolation="DEFAULT"/>
            <tx:method name="delete*" propagation="NESTED" read-only="false"
                       rollback-for="java.lang.RuntimeException"/>
            <tx:method name="update*" propagation="REQUIRED" read-only="false"
                       rollback-for="java.lang.RuntimeException"/>
            <tx:method name="check*" propagation="REQUIRED" read-only="false"
                       rollback-for="java.lang.RuntimeException"/>
            <tx:method name="print*" propagation="REQUIRED" read-only="false"
                       rollback-for="java.lang.RuntimeException"/>
            <tx:method name="*" propagation="REQUIRED" read-only="false" isolation="DEFAULT"
                       rollback-for="java.lang.RuntimeException"/>
        </tx:attributes>
    </tx:advice>
<aop:config proxy-target-class="false">
        <aop:pointcut id="pc" expression="execution(public * com.zhuguang.jack.service..*.*(..))"/>
        <aop:advisor pointcut-ref="pc" advice-ref="userTxAdvice"/>    增强(对public * com.zhuguang.jack.service..*.*(..)目标方法的增强,就是开启事务关闭事务,对应的就是前置后置增强,就是环绕增强,前面是开始事务后面是关闭事务,)
    </aop:config>
<tx:advice>是增强。做了哪些工作。
public class TxNamespaceHandler extends NamespaceHandlerSupport {
    @Override
    public void init() {
        registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser());   //解析</tx:advice>标签。
        registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
    }
}
TxAdviceBeanDefinitionParser  extends AbstractSingleBeanDefinitionParser    extends AbstractBeanDefinitionParser
//解析<tx:advice>标签,
public final BeanDefinition parse(Element element, ParserContext parserContext) {   //element  =  tx:advice
        AbstractBeanDefinition definition = parseInternal(element, parserContext);   // tx:advice的bean定义,//解析<tx:attributes>,<tx:method>子标签,TransactionInterceptor,
        if (definition != null && !parserContext.isNested()) {
            try {
                String id = resolveId(element, definition, parserContext);    //解析id属性
                if (!StringUtils.hasText(id)) {
                    parserContext.getReaderContext().error(ment);
                }
                String[] aliases = new String[0];
                String name = element.getAttribute(NAME_ATTRIBUTE);//name
                if (StringUtils.hasLength(name)) {
                    aliases = StringUtils.trimArrayElements(StringUtils.commaDelimitedListToStringArray(name));
                }
                BeanDefinitionHolder holder = new BeanDefinitionHolder(definition, id, aliases);  //TransactionInterceptor,
                registerBeanDefinition(holder, parserContext.getRegistry());   // tx:advice的bean定义注册到spring容器。
            }
        }
        return definition;
    }
//解析<tx:attributes>,<tx:method>子标签,
protected final AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
        BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();   //BeanDefinitionBuilder里面有GenericBeanDefinition,GenericBeanDefinition的beanClass属性为TransactionInterceptor,
        String parentName = getParentName(element);
        if (parentName != null) {
            builder.getRawBeanDefinition().setParentName(parentName);
        }
        Class<?> beanClass = getBeanClass(element);   //TransactionInterceptor,是真正实例化的,
        if (beanClass != null) {
            builder.getRawBeanDefinition().setBeanClass(beanClass);  //设置GenericBeanDefinition的beanClass属性为TransactionInterceptor,
        }
        builder.getRawBeanDefinition().setSource(parserContext.extractSource(element));
        doParse(element, parserContext, builder);    //解析,builder  =  BeanDefinitionBuilder。element  =  tx:advice,//解析<tx:attributes>,<tx:method>子标签,
        return builder.getBeanDefinition();   //GenericBeanDefinition
    }
public static BeanDefinitionBuilder genericBeanDefinition() {
        BeanDefinitionBuilder builder = new BeanDefinitionBuilder();
        builder.beanDefinition = new GenericBeanDefinition();    //返回的就是这个GenericBeanDefinition
        return builder;
    }
//解析<tx:attributes>,<tx:method>子标签,
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {   //把属性加到TransactionInterceptor里面去,
        builder.addPropertyReference("transactionManager", TxNamespaceHandler.getTransactionManagerName(element));

        List<Element> txAttributes = DomUtils.getChildElementsByTagName(element, ATTRIBUTES_ELEMENT);  //拿到<tx:attributes>属性,
        if (txAttributes.size() > 1) {   //只能有一个<tx:attributes>属性,
            parserContext.getReaderContext().error(at most once inside element <advice>", element);
        }
        else if (txAttributes.size() == 1) {
            Element attributeSourceElement = txAttributes.get(0);   //<tx:attributes>
            RootBeanDefinition attributeSourceDefinition = parseAttributeSource(attributeSourceElement, parserContext);   //解析<tx:method>子标签
            builder.addPropertyValue("transactionAttributeSource", attributeSourceDefinition);
        }
    }
public BeanDefinitionBuilder addPropertyReference(String name, String beanName) {
        this.beanDefinition.getPropertyValues().add(name, new RuntimeBeanReference(beanName));   //IOC的时候去实例化,
        return this;
    }
//解析<tx:method>子标签,
private RootBeanDefinition parseAttributeSource(Element attrEle, ParserContext parserContext) {
        List<Element> methods = DomUtils.getChildElementsByTagName(attrEle, METHOD_ELEMENT);   //拿到<tx:method>子标签。<tx:method name="purchase" propagation="REQUIRED" isolation="READ_COMMITTED" />拦截purchase方法,aop:pointcut已经做了拦截,这里再拦截,之后指定的方法才会有事务,
        ManagedMap<TypedStringValue, RuleBasedTransactionAttribute> transactionAttributeMap =
            new ManagedMap<TypedStringValue, RuleBasedTransactionAttribute>(methods.size());
        transactionAttributeMap.setSource(parserContext.extractSource(attrEle));

        for (Element methodEle : methods) {
            String name = methodEle.getAttribute(METHOD_NAME_ATTRIBUTE);   //方法的名字,
            TypedStringValue nameHolder = new TypedStringValue(name);
            nameHolder.setSource(parserContext.extractSource(methodEle));

            RuleBasedTransactionAttribute attribute = new RuleBasedTransactionAttribute();
            String propagation = methodEle.getAttribute(PROPAGATION_ATTRIBUTE);   //拿到方法的传播属性,
            String isolation = methodEle.getAttribute(ISOLATION_ATTRIBUTE);  //拿到方法的隔离级别,
            String timeout = methodEle.getAttribute(TIMEOUT_ATTRIBUTE);//拿到超时时间,
            String readOnly = methodEle.getAttribute(READ_ONLY_ATTRIBUTE);   //是否是只读事务,
            if (StringUtils.hasText(propagation)) {//设置到attribute 
                attribute.setPropagationBehaviorName(RuleBasedTransactionAttribute.PREFIX_PROPAGATION + propagation);
            }
            if (StringUtils.hasText(isolation)) {//设置到attribute 
                attribute.setIsolationLevelName(RuleBasedTransactionAttribute.PREFIX_ISOLATION + isolation);
            }
            if (StringUtils.hasText(timeout)) {
                try {
                    attribute.setTimeout(Integer.parseInt(timeout));//设置到attribute 
                }
            }
            if (StringUtils.hasText(readOnly)) {//设置到attribute 
                attribute.setReadOnly(Boolean.valueOf(methodEle.getAttribute(READ_ONLY_ATTRIBUTE)));
            }

            List<RollbackRuleAttribute> rollbackRules = new LinkedList<RollbackRuleAttribute>();  //事务回滚,遇到异常回滚,异常有很多,rollback-for就是遇到这个异常就回滚,no-rollback-for就是遇到这个异常不回滚。
            if (methodEle.hasAttribute(ROLLBACK_FOR_ATTRIBUTE)) {
                String rollbackForValue = methodEle.getAttribute(ROLLBACK_FOR_ATTRIBUTE);
                addRollbackRuleAttributesTo(rollbackRules,rollbackForValue);//添加rollback-for到rollbackRules,
            }
            if (methodEle.hasAttribute(NO_ROLLBACK_FOR_ATTRIBUTE)) {
                String noRollbackForValue = methodEle.getAttribute(NO_ROLLBACK_FOR_ATTRIBUTE);
                addNoRollbackRuleAttributesTo(rollbackRules,noRollbackForValue);//添加no-rollback-for到rollbackRules,
            }
            attribute.setRollbackRules(rollbackRules);//rollback-for,no-rollback-for添加到属性attribute

            transactionAttributeMap.put(nameHolder, attribute);   //属性跟方法绑定,
        }

        RootBeanDefinition attributeSourceDefinition = new RootBeanDefinition(NameMatchTransactionAttributeSource.class);   //bean定义(事务的属性),
        attributeSourceDefinition.setSource(parserContext.extractSource(attrEle));
        attributeSourceDefinition.getPropertyValues().add("nameMap", transactionAttributeMap);
        return attributeSourceDefinition;
    }
Spring事物传播行为 事务嵌套
PROPAGATION_REQUIRED(默认)—如果当前有事务,就用当前事务(就使用外层的事务,不使用自己的事务),如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS--支持当前事务(外层事务),如果当前没有事务,就以非事务方式执行。//如果外层方法没有事务,就会以非事务进行执行。
PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常(使用外层事务)。 
PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起(不用外层事务,就跟外层没有影响了)。 
PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起(失效)。(外层有事务,就已非事务执行,外层事务失效) 
PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。
默认传播行为为REQUIRED
事务的隔离级别:spring的隔离级别(一个事务不能读到另一个没有提交的事务的数据,事务就是加锁),数据库的隔离级别。
<!-- 配置AOP -->
    <aop:config>
        <!-- 配置切入点表达式 -->
        <aop:pointcut expression="execution(* cn.sdut.xml.BookShopXMLService.*(..))" id="pointcut" />
        <!-- 将事务通知和切入点表达式关联起来 -->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut" />
    </aop:config>
解析aop:config标签。

public BeanDefinition parse(Element element, ParserContext parserContext) {
        CompositeComponentDefinition compositeDef =
                new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));
        parserContext.pushContainingComponent(compositeDef);

        configureAutoProxyCreator(parserContext, element);

        List<Element> childElts = DomUtils.getChildElements(element);
        for (Element elt: childElts) {
            String localName = parserContext.getDelegate().getLocalName(elt);
            if (POINTCUT.equals(localName)) {
                parsePointcut(elt, parserContext);
            }
            else if (ADVISOR.equals(localName)) {
                parseAdvisor(elt, parserContext);
            }
            else if (ASPECT.equals(localName)) {
                parseAspect(elt, parserContext);
            }
        }
        return null;
    }
解析aop:pointcut标签:
private AbstractBeanDefinition parsePointcut(Element pointcutElement, ParserContext parserContext) {
        pointcutDefinition = createPointcutDefinition(expression);

        String pointcutBeanName = id;
        parserContext.getRegistry().registerBeanDefinition(pointcutBeanName, pointcutDefinition);  //AspectJExpressionPointcut添加到spring的容器,

        return pointcutDefinition;
    }
解析aop:advisor标签:
private void parseAdvisor(Element advisorElement, ParserContext parserContext) {
        AbstractBeanDefinition advisorDef = createAdvisorBeanDefinition(advisorElement, parserContext);   //DefaultBeanFactoryPointcutAdvisor添加到spring容器,
        String id = advisorElement.getAttribute(ID);
        try {
            this.parseState.push(new AdvisorEntry(id));
            String advisorBeanName = id;
            if (StringUtils.hasText(advisorBeanName)) {
                parserContext.getRegistry().registerBeanDefinition(advisorBeanName, advisorDef);
            }

            Object pointcut = parsePointcutProperty(advisorElement, parserContext);   //pointcut属性,
            if (pointcut instanceof BeanDefinition) {
                advisorDef.getPropertyValues().add(POINTCUT, pointcut);
                parserContext.registerComponent(
                        new AdvisorComponentDefinition(advisorBeanName, advisorDef, (BeanDefinition) pointcut));
            }
            else if (pointcut instanceof String) {
                advisorDef.getPropertyValues().add(POINTCUT, new RuntimeBeanReference((String) pointcut));
                parserContext.registerComponent(
                        new AdvisorComponentDefinition(advisorBeanName, advisorDef));
            }
        }
    }
解析tx:advice标签就是把GenericBeanDefinition加到spring的容器,解析aop:config标签就是把AspectJExpressionPointcut和DefaultBeanFactoryPointcutAdvisor加到spring容器。
解析bookShopXMLService(事务也是AOP的实现之一),

createBean-----resolveBeforeInstantiation

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
        Object bean = null;
        if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
            if (mbd.hasBeanClass() && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
                bean = applyBeanPostProcessorsBeforeInstantiation(mbd.getBeanClass(), beanName);
            }
        }
        return bean;
    }
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
                if (result != null) {
                    return result;
                }
            }
        }
        return null;
    }
AbstractAutoProxyCreator类:
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
            if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return null;
            }
        }
        if (beanName != null) {
            TargetSource targetSource = getCustomTargetSource(beanClass, beanName);  //BookShopXMLService,bookShopXMLService,返回null。
            if (targetSource != null) {
                this.targetSourcedBeans.add(beanName);
                Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
                Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
                this.proxyTypes.put(cacheKey, proxy.getClass());
                return proxy;
            }
        }
        return null;
    }
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
        List<Advisor> candidateAdvisors = findCandidateAdvisors(); //DefaultBeanFactoryPointcutAdvisor
        for (Advisor advisor : candidateAdvisors) {
            if (advisor instanceof AspectJPointcutAdvisor) {
                if (((AbstractAspectJAdvice) advisor.getAdvice()).getAspectName().equals(beanName)) {
                    return true;
                }
            }
        }
        return super.shouldSkip(beanClass, beanName);
    }
public List<Advisor> findAdvisorBeans() {
        String[] advisorNames = null;
        synchronized (this) {
            advisorNames = this.cachedAdvisorBeanNames;   //DefaultBeanFactoryPointcutAdvisor就是<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut" />标签,
        }

        List<Advisor> advisors = new LinkedList<Advisor>();
        for (String name : advisorNames) {
            if (isEligibleBean(name)) {
                else {
                    try {
                        advisors.add(this.beanFactory.getBean(name, Advisor.class));  //创建DefaultBeanFactoryPointcutAdvisor实例,
                    }
                    }
                }
            }
        }
        return advisors;  //DefaultBeanFactoryPointcutAdvisor
    }
doCreateBean-----initializeBean-----applyBeanPostProcessorsAfterInitialization,
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) {
        Object result = existingBean;
        for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
            result = beanProcessor.postProcessAfterInitialization(result, beanName);//返回jdk动态代理:[ExposeInvocationInterceptor.ADVISOR, DefaultBeanFactoryPointcutAdvisor: pointcut [AspectJExpressionPointcut: () execution(* cn.sdut.xml.BookShopXMLService.*(..))]; advice bean 'txAdvice' = advice = TransactionInterceptor(<tx:advice>标签解析成的类)]; targetSource [[BookShopXMLService]];
            if (result == null) {
                return result;
            }
        }
        return result;
    }
AbstractAutoProxyCreatorpublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean != null) {
            Object cacheKey = getCacheKey(bean.getClass(), beanName);
            if (!this.earlyProxyReferences.contains(cacheKey)) {
                return wrapIfNecessary(bean, beanName, cacheKey);   //返回jdk动态代理:[ExposeInvocationInterceptor.ADVISOR, DefaultBeanFactoryPointcutAdvisor: pointcut [AspectJExpressionPointcut: () execution(* cn.sdut.xml.BookShopXMLService.*(..))]; advice bean 'txAdvice' = advice = TransactionInterceptor(<tx:advice>标签解析成的类)]; targetSource [[BookShopXMLService]];
            }
        }
        return bean;
    }
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }

        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);//[ExposeInvocationInterceptor.ADVISOR, 
DefaultBeanFactoryPointcutAdvisor: pointcut [AspectJExpressionPointcut: () execution(* cn.sdut.xml.BookShopXMLService.*(..))]; advice bean 'txAdvice' = advice = TransactionInterceptor(<tx:advice>标签解析成的类)]
        if (specificInterceptors != DO_NOT_PROXY) {
            this.advisedBeans.put(cacheKey, Boolean.TRUE);
            Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));   //返回jdk的动态代理,[ExposeInvocationInterceptor.ADVISOR, DefaultBeanFactoryPointcutAdvisor: pointcut [AspectJExpressionPointcut: () execution(* cn.sdut.xml.BookShopXMLService.*(..))]; advice bean 'txAdvice' = advice = TransactionInterceptor(<tx:advice>标签解析成的类)]; targetSource [[BookShopXMLService]];
            this.proxyTypes.put(cacheKey, proxy.getClass());
            return proxy;
        }
    }
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
        List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);//[ExposeInvocationInterceptor.ADVISOR, 
DefaultBeanFactoryPointcutAdvisor: pointcut [AspectJExpressionPointcut: () execution(* cn.sdut.xml.BookShopXMLService.*(..))]; advice bean 'txAdvice' = advice = TransactionInterceptor(<tx:advice>标签解析成的类)]
        if (advisors.isEmpty()) {
            return DO_NOT_PROXY;
        }
        return advisors.toArray();
    }
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
        List<Advisor> candidateAdvisors = findCandidateAdvisors();  //DefaultBeanFactoryPointcutAdvisor,
        List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
        extendAdvisors(eligibleAdvisors);  //解析advice-ref属性,
        if (!eligibleAdvisors.isEmpty()) {
            eligibleAdvisors = sortAdvisors(eligibleAdvisors);
        }
        return eligibleAdvisors;//[ExposeInvocationInterceptor.ADVISOR, 
DefaultBeanFactoryPointcutAdvisor: pointcut [AspectJExpressionPointcut: () execution(* cn.sdut.xml.BookShopXMLService.*(..))]; advice bean 'txAdvice' = advice = TransactionInterceptor(<tx:advice>标签解析成的类) ]
    }
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
        MethodMatcher methodMatcher = pc.getMethodMatcher();  //AspectJExpressionPointcut: () execution(* cn.sdut.xml.BookShopXMLService.*(..)),
        IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
        if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
            introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;  //AspectJExpressionPointcut: () execution(* cn.sdut.xml.BookShopXMLService.*(..)),
        }

        Set<Class<?>> classes = new HashSet<Class<?>>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
        classes.add(targetClass);//[class cn.sdut.xml.BookShopXMLService]
        for (Class<?> clazz : classes) {
            Method[] methods = clazz.getMethods();
            for (Method method : methods) {//public void cn.sdut.xml.BookShopXMLService.purchase(int),
                if ((introductionAwareMethodMatcher != null &&
                        introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) || //YES,TRUE
                        methodMatcher.matches(method, targetClass)) {
                    return true;
                }
            }
        }

        return false;
    }
public boolean matches(Method method, Class<?> targetClass, boolean beanHasIntroductions) {
        checkReadyToMatch();
        Method targetMethod = AopUtils.getMostSpecificMethod(method, targetClass);  //public void cn.sdut.xml.BookShopXMLService.purchase(int),class cn.sdut.xml.BookShopXMLService。返回public void cn.sdut.xml.BookShopXMLService.purchase(int)。
        ShadowMatch shadowMatch = getShadowMatch(targetMethod, method); //YES,TRUE
        if (shadowMatch.alwaysMatches()) {
            return true;
        }
    }
private ShadowMatch getShadowMatch(Method targetMethod, Method originalMethod) {
        ShadowMatch shadowMatch = this.shadowMatchCache.get(targetMethod);  //null,shadowMatchCache = {},
        if (shadowMatch == null) {
            synchronized (this.shadowMatchCache) {
                Method methodToMatch = targetMethod;  //public void cn.sdut.xml.BookShopXMLService.purchase(int)。
                PointcutExpression fallbackPointcutExpression = null;
                shadowMatch = this.shadowMatchCache.get(methodToMatch);//null,
                if (shadowMatch == null) {//
                    try {
                        shadowMatch = this.pointcutExpression.matchesMethodExecution(targetMethod); //YES,TRUE
                    }
                }
            }
        }
        return shadowMatch; //YES,TRUE
    }
public ShadowMatch matchesMethodExecution(Method aMethod) {  //public void cn.sdut.xml.BookShopXMLService.purchase(int),
        ShadowMatch match = matchesExecution(aMethod); //YES,TRUE
        return match;
    }
private ShadowMatch matchesExecution(Member aMember) {
        Shadow s = ReflectionShadow.makeExecutionShadow(world, aMember, this.matchContext);//method-execution(void cn.sdut.xml.BookShopXMLService.purchase(int)),
        ShadowMatchImpl sm = getShadowMatch(s);  //YES,TRUE
        sm.setSubject(aMember);
        sm.setWithinCode(null);
        sm.setWithinType(aMember.getDeclaringClass());
        return sm; //YES,TRUE
    }
private ShadowMatchImpl getShadowMatch(Shadow forShadow) {//forShadow   =   method-execution(void cn.sdut.xml.BookShopXMLService.purchase(int)),
        org.aspectj.util.FuzzyBoolean match = pointcut.match(forShadow);//return FuzzyBoolean.YES;
        Test residueTest = Literal.TRUE;
        ExposedState state = getExposedState();
        if (match.maybeTrue()) {
            residueTest = pointcut.findResidue(forShadow, state);   //TRUE
        }
        ShadowMatchImpl sm = new ShadowMatchImpl(match, residueTest, state, parameters);
        sm.setMatchingContext(this.matchContext);
        return sm;//YES,TRUE
    }
public final FuzzyBoolean match(Shadow shadow) {
        if (shadow.getKind().isSet(couldMatchKinds())) {
            ret = matchInternal(shadow);//return FuzzyBoolean.YES;
        }
        lastMatchedShadowId = shadow.shadowId;
        lastMatchedShadowResult = ret;
        return ret;//return FuzzyBoolean.YES;
    }

protected FuzzyBoolean matchInternal(Shadow shadow) {
        if (!signature.matches(shadow.getMatchingSignature(), shadow.getIWorld(), this.kind == Shadow.MethodCall)) {
            if (kind == Shadow.MethodCall) {
                warnOnConfusingSig(shadow);
            }
            return FuzzyBoolean.NO;
        }
        return FuzzyBoolean.YES;
    }
protected void extendAdvisors(List<Advisor> candidateAdvisors) {
        AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(candidateAdvisors);//candidateAdvisors  =  DefaultBeanFactoryPointcutAdvisor: pointcut [AspectJExpressionPointcut: () execution(* cn.sdut.xml.BookShopXMLService.*(..))]; advice bean 'txAdvice'。开始解析<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut" />标签里面的advice-ref属性。
    }
public static boolean makeAdvisorChainAspectJCapableIfNecessary(List<Advisor> advisors) {
        if (!advisors.isEmpty()) {  //DefaultBeanFactoryPointcutAdvisor: pointcut [AspectJExpressionPointcut: () execution(* cn.sdut.xml.BookShopXMLService.*(..))]; advice bean 'txAdvice' = advice = TransactionInterceptor(<tx:advice>标签解析成的类)。
            boolean foundAspectJAdvice = false;
            for (Advisor advisor : advisors) {
                if (isAspectJAdvice(advisor)) {
                    foundAspectJAdvice = true;
                }
            }
            if (foundAspectJAdvice && !advisors.contains(ExposeInvocationInterceptor.ADVISOR)) {
                advisors.add(0, ExposeInvocationInterceptor.ADVISOR);
                return true;
            }
        }
        return false;
    }
public Advice getAdvice() {
        synchronized (this.adviceMonitor) {
            if (this.advice == null && this.adviceBeanName != null) {
                this.advice = this.beanFactory.getBean(this.adviceBeanName, Advice.class);   //adviceBeanName  =  txAdvice,获取txAdvice实例。this  =  DefaultBeanFactoryPointcutAdvisor,
            }
            return this.advice;
        }
    }
protected Object createProxy(Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {

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

        if (!proxyFactory.isProxyTargetClass()) {
            if (shouldProxyTargetClass(beanClass, beanName)) {
                proxyFactory.setProxyTargetClass(true);
            }
            else {
                evaluateProxyInterfaces(beanClass, proxyFactory);//beanClass  =  class cn.sdut.xml.BookShopXMLService,
            }
        }

        Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
        for (Advisor advisor : advisors) {
            proxyFactory.addAdvisor(advisor);//advisors   =   [ExposeInvocationInterceptor.ADVISOR, 
DefaultBeanFactoryPointcutAdvisor: pointcut [AspectJExpressionPointcut: () execution(* cn.sdut.xml.BookShopXMLService.*(..))]; advice bean 'txAdvice' = advice = TransactionInterceptor(<tx:advice>标签解析成的类)]
        }

        proxyFactory.setTargetSource(targetSource);
        customizeProxyFactory(proxyFactory);

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

        return proxyFactory.getProxy(this.proxyClassLoader);    //proxyFactory里面有[ExposeInvocationInterceptor.ADVISOR, DefaultBeanFactoryPointcutAdvisor: pointcut [AspectJExpressionPointcut: () execution(* cn.sdut.xml.BookShopXMLService.*(..))]; advice bean 'txAdvice' = advice = TransactionInterceptor(<tx:advice>标签解析成的类)]; targetSource [[BookShopXMLService]];
    }
方法的调用:
AA as = (AA) context.getBean("bookShopXMLService");   
//as是jdk的动态代理,cn.sdut.xml.BookShopXMLService@e6516e,里面的h = JdkDynamicAopProxy@6c9fed53,h里面的advised = ProcyFactory = ProxyFactory: 2 advisors [ExposeInvocationInterceptor.ADVISOR, DefaultBeanFactoryPointcutAdvisor: pointcut [AspectJExpressionPointcut: () execution(* BookShopXMLService.*(..))]; advice bean 'txAdvice' = TransactionInterceptor@5aabbb29]; targetSource  [BookShopXMLService@e6516e]]; 

as.purchase(1);
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);   //advised  =  ProxyFactory,method = AA.purchase(int),targetClass = class cn.sdut.xml.BookShopXMLService。拿到所有的MeathodIntesept。返回ExposeInvocationInterceptor@548e76f1, TransactionInterceptor@5aabbb29,

            else {
                invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);  //proxy = BookShopXMLService,target = BookShopXMLService,method = AA.purchase(int),args = [1],targetClass = BookShopXMLService,chain = ExposeInvocationInterceptor@548e76f1, TransactionInterceptor@5aabbb29,
                retVal = invocation.proceed();   //链式调用,invocation = ReflectiveMethodInvocation: public abstract void cn.sdut.xml.AA.purchase(int); target is of class [cn.sdut.xml.BookShopXMLService],
            }

            Class<?> returnType = method.getReturnType();
            return retVal;
        }
    }
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) {
        MethodCacheKey cacheKey = new MethodCacheKey(method);
        List<Object> cached = this.methodCache.get(cacheKey);
        if (cached == null) {
            cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
                    this, method, targetClass);  //this =  ProxyFactory,
            this.methodCache.put(cacheKey, cached);
        }
        return cached;//ExposeInvocationInterceptor@548e76f1, TransactionInterceptor@5aabbb29,
    }
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
            Advised config, Method method, Class<?> targetClass) {  //config = ProxyFactory,method = AA.purchase(int),targetClass = BookShopXMLService,

        List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
        boolean hasIntroductions = hasMatchingIntroductions(config, targetClass);  //fasle,
        AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
        for (Advisor advisor : config.getAdvisors()) {
            if (advisor instanceof PointcutAdvisor) {//ExposeInvocationInterceptor.ADVISOR,DefaultBeanFactoryPointcutAdvisor,
                PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
                if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(targetClass)) {
                    MethodInterceptor[] interceptors = registry.getInterceptors(advisor);//TransactionInterceptor@5aabbb29
                    MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();//AspectJExpressionPointcut: () execution(* cn.sdut.xml.BookShopXMLService.*(..))
                    if (MethodMatchers.matches(mm, method, targetClass, hasIntroductions)) {
                        if (mm.isRuntime()) {
                        }
                        else {
                            interceptorList.addAll(Arrays.asList(interceptors));
                        }
                    }
                }
            }
        }
        return interceptorList;  //ExposeInvocationInterceptor@548e76f1, TransactionInterceptor@5aabbb29,
    }
private static boolean hasMatchingIntroductions(Advised config, Class<?> targetClass) {  //config  =  ProxyFactory,targetClass  =  BookShopXMLService。
        for (int i = 0; i < config.getAdvisors().length; i++) {//ExposeInvocationInterceptor.ADVISOR,DefaultBeanFactoryPointcutAdvisor(TransactionInterceptor@5aabbb29,AspectJExpressionPointcut: () execution(* cn.sdut.xml.BookShopXMLService.*(..)))
            Advisor advisor = config.getAdvisors()[i];//ExposeInvocationInterceptor.ADVISOR(不走),DefaultBeanFactoryPointcutAdvisor(不走),
            if (advisor instanceof IntroductionAdvisor) {
                IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
                if (ia.getClassFilter().matches(targetClass)) {
                    return true;
                }
            }
        }
        return false;
    }
public Object proceed() throws Throwable {  //interceptorsAndDynamicMethodMatchers = ExposeInvocationInterceptor@548e76f1, TransactionInterceptor@5aabbb29,this = ReflectiveMethodInvocation: public abstract void cn.sdut.xml.AA.purchase(int); target is of class [cn.sdut.xml.BookShopXMLService]
        if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
            return invokeJoinpoint();
        }

        Object interceptorOrInterceptionAdvice =
                this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);  //ExposeInvocationInterceptor@548e76f1,
        if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
        }
        else {
            return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
        }
    }
ExposeInvocationInterceptor@548e76f1的invoke方法:
public Object invoke(MethodInvocation mi) throws Throwable {
        MethodInvocation oldInvocation = invocation.get();  //null
        invocation.set(mi);   //mi = ReflectiveMethodInvocation: public abstract void cn.sdut.xml.AA.purchase(int); target is of class [cn.sdut.xml.BookShopXMLService]
        try {
            return mi.proceed();   //又进去,链式调用第二个
        }
        finally {
            invocation.set(oldInvocation);
        }
    }
public Object proceed() throws Throwable {
        if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
            return invokeJoinpoint();//调用目标方法,
        }

        Object interceptorOrInterceptionAdvice =
                this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);   //TransactionInterceptor@5aabbb29,
        if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
        }
        else {
            return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
        }
    }
//TransactionInterceptor@5aabbb29类的invoke,
public Object invoke(final MethodInvocation invocation) throws Throwable {//invocation = ReflectiveMethodInvocation: public abstract void cn.sdut.xml.AA.purchase(int); target is of class [cn.sdut.xml.BookShopXMLService],
        Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);  //class cn.sdut.xml.BookShopXMLService

        return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
            @Override
            public Object proceedWithInvocation() throws Throwable {
                return invocation.proceed();  //又调进去,invocation  =  ReflectiveMethodInvocation,
            }
        });
    }
protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation) {

        final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);//getTransactionAttributeSource() = {purchase=PROPAGATION_REQUIRED,ISOLATION_READ_COMMITTED},根据方法的名字拿到这个方法对应的事务属性(隔离级别,传播属性,事务回滚的异常,只读事务),返回PROPAGATION_REQUIRED,ISOLATION_READ_COMMITTED
        final PlatformTransactionManager tm = determineTransactionManager(txAttr);   //事务管理,transactionManager管理开启关闭事务,dataSource是一个连接池(java,sql,connection),一切事务都是基于连接来做的,
        final String joinpointIdentification = methodIdentification(method, targetClass);  //当前被调用的方法cn.sdut.xml.BookShopXMLService.purchase,
        if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
            TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);  //开启事务,tm = DataSourceTransactionManager,txAttr = PROPAGATION_REQUIRED,ISOLATION_READ_COMMITTED。joinpointIdentification = BookShopXMLService.purchase,返回事务信息(有管理平台,事务属性,老的事务信息)。
            Object retVal = null;
            try {
                retVal = invocation.proceedWithInvocation();//调到上面invokeWithinTransaction的匿名对象的方法去了。又走链式调用,就调到目标方法去了。
            }
            catch (Throwable ex) {//目标方法有异常,事务回滚。
                completeTransactionAfterThrowing(txInfo, ex);
                throw ex;
            }
            finally {
                cleanupTransactionInfo(txInfo);
            }
            commitTransactionAfterReturning(txInfo);
            return retVal;
        }
    }
protected TransactionInfo createTransactionIfNecessary(
            PlatformTransactionManager tm, TransactionAttribute txAttr, final String joinpointIdentification) {
        TransactionStatus status = null;
        if (txAttr != null) {
            if (tm != null) {
                status = tm.getTransaction(txAttr);   //txAttr = PROPAGATION_REQUIRED,ISOLATION_READ_COMMITTED。开启了事务了。
            }
        }
        return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);//准备事务的信息,
    }
public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
        Object transaction = doGetTransaction();    //返回的对象里面有connection,DataSourceTransactionManager$DataSourceTransactionObject,
        if (definition == null) {
            definition = new DefaultTransactionDefinition();  //PROPAGATION_REQUIRED,ISOLATION_READ_COMMITTED(事务传播属性,事务隔离级别,回滚异常),
        }
        if (isExistingTransaction(transaction)) {//是否已经存在事务,不是第一次进来。方法嵌套就会有事务的嵌套。
            return handleExistingTransaction(definition, transaction, debugEnabled);
        }
        else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
                definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
            definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
            SuspendedResourcesHolder suspendedResources = suspend(null);   //挂起事务(挂起外层方法的事务),第一次进来没有事务,就是空事务,返回null,
            try {
                boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
                DefaultTransactionStatus status = newTransactionStatus(
                        definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);  //事务状态,
                doBegin(transaction, definition);  //开启事务,transaction = DataSourceTransactionManager$DataSourceTransactionObject,definition = PROPAGATION_REQUIRED,ISOLATION_READ_COMMITTED。
                prepareSynchronization(status, definition);//同步
                return status;  //返回事务状态,
            }
            }
        }
    }
protected Object doGetTransaction() {
        DataSourceTransactionObject txObject = new DataSourceTransactionObject();   //里面有connection,DataSourceTransactionObject 就是事务对象(标明当前事务是否是最新的事务,connectionHolder里面有connectionHandler里面有connection)。
        txObject.setSavepointAllowed(isNestedTransactionAllowed());  //是否允许嵌套事务,
        ConnectionHolder conHolder =
            (ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource);  //dataSource = 数据库连接池,第一次是空的,
        txObject.setConnectionHolder(conHolder, false);
        return txObject;
    }
protected void doBegin(Object transaction, TransactionDefinition definition) { //开启事务,
        DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
        Connection con = null;
        try {
            if (txObject.getConnectionHolder() == null ||
                    txObject.getConnectionHolder().isSynchronizedWithTransaction()) {   //第一次进来是空,会去连接池里面拿到一个对象。
                Connection newCon = this.dataSource.getConnection();  //拿到一个连接,
                txObject.setConnectionHolder(new ConnectionHolder(newCon), true);  //连接塞到事务对象中,并且是新的,
            }

            txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
            con = txObject.getConnectionHolder().getConnection();  //就是前面从连接池拿到的连接,

            Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);//返回隔离级别,
            txObject.setPreviousIsolationLevel(previousIsolationLevel);//隔离级别塞到事务对象中,

            if (con.getAutoCommit()) {//连接中自动提交为true,
                txObject.setMustRestoreAutoCommit(true);
                con.setAutoCommit(false);//连接的自动提交设置为false。开启事务。
            }
            txObject.getConnectionHolder().setTransactionActive(true);//事务是活动的设置为true,

            if (txObject.isNewConnectionHolder()) {//是不是新的ConnectionHolder,
                TransactionSynchronizationManager.bindResource(getDataSource(), txObject.getConnectionHolder());
            }
        }
    }
public static Integer prepareConnectionForTransaction(Connection con, TransactionDefinition definition) {
        if (definition != null && definition.isReadOnly()) {
            con.setReadOnly(true);//设置只读
        }
        Integer previousIsolationLevel = null;
        if (definition != null && definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
            int currentIsolation = con.getTransactionIsolation();  //拿到数据库隔离级别,
            if (currentIsolation != definition.getIsolationLevel()) {//数据库的隔离级别和spring的隔离级别不一样,
                previousIsolationLevel = currentIsolation;
                con.setTransactionIsolation(definition.getIsolationLevel());//就把spring的隔离级别设置成当前连接的隔离级别,
            }
        }
        return previousIsolationLevel;//返回隔离级别,
    }
protected TransactionInfo prepareTransactionInfo(PlatformTransactionManager tm,
            TransactionAttribute txAttr, String joinpointIdentification, TransactionStatus status) {
        TransactionInfo txInfo = new TransactionInfo(tm, txAttr, joinpointIdentification);  //包装了事务的一些信息(事务管理平台,事务的属性,pointcut),
        if (txAttr != null) {
            txInfo.newTransactionStatus(status);//事务的状态塞到txInfo里面去,
        }
        else {
        }
        txInfo.bindToThread();
        return txInfo;
    }
private void bindToThread() {
            this.oldTransactionInfo = transactionInfoHolder.get(); //老的事务信息,
            transactionInfoHolder.set(this);//当前事务信息塞到ThreadLocal中去,
        }
protected void commitTransactionAfterReturning(TransactionInfo txInfo) {
        if (txInfo != null && txInfo.hasTransaction()) {
            txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());//提交事务
        }
    }


public final void commit(TransactionStatus status) throws TransactionException {
        DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;//事务状态
        processCommit(defStatus);
    }
private void processCommit(DefaultTransactionStatus status) throws TransactionException {
        try {
            try {
                else if (status.isNewTransaction()) {
                    doCommit(status);
                }
            }

        }
        finally {
            cleanupAfterCompletion(status);
        }
    }
protected void doCommit(DefaultTransactionStatus status) {
        DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
        Connection con = txObject.getConnectionHolder().getConnection();
        try {
            con.commit();//拿到连接进行commit,
        }
    }
目标方法有异常,事务回滚。
protected void completeTransactionAfterThrowing(TransactionInfo txInfo, Throwable ex) {
        if (txInfo != null && txInfo.hasTransaction()) {//有事务,事务状态不为空,
            if (txInfo.transactionAttribute.rollbackOn(ex)) {//异常是 RuntimeException ||  Error都会回滚,
                try {
                    txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
                }
            }
            else {//异常不是 RuntimeException ||  Error就不回滚,就会提交。
                try {
                    txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
                }
            }
        }
    }
public final void rollback(TransactionStatus status) throws TransactionException {
        if (status.isCompleted()) {
            throw new IllegalTransactionStateException(n");
        }

        DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;//拿到事务状态,
        processRollback(defStatus);
    }
private void processRollback(DefaultTransactionStatus status) {
        try {
            try {
                triggerBeforeCompletion(status);
                if (status.hasSavepoint()) {   //嵌套事务,有savepoint,
                    status.rollbackToHeldSavepoint();
                }
                else if (status.isNewTransaction()) {   //是一个新事物
                    doRollback(status);
                }
                else if (status.hasTransaction()) {
                    if (status.isLocalRollbackOnly() || isGlobalRollbackOnParticipationFailure()) {
                        doSetRollbackOnly(status);
                    }
                    else {
                    }
                }
            }
            triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
        }
        finally {
            cleanupAfterCompletion(status);
        }
    }
protected void doRollback(DefaultTransactionStatus status) {
        DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
        Connection con = txObject.getConnectionHolder().getConnection();
        try {
            con.rollback();//拿到连接,
        }
    }

public void rollbackToHeldSavepoint() throws TransactionException {
        getSavepointManager().rollbackToSavepoint(getSavepoint());
        setSavepoint(null);
    }
方法嵌套就会有事务的嵌套。
private TransactionStatus handleExistingTransaction(TransactionDefinition definition, Object transaction, boolean debugEnabled){

        if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {//事务的传播属性
        }

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

        if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {//事务的传播属性,是嵌套
            if (useSavepointForNestedTransaction()) {
                DefaultTransactionStatus status = prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);//状态,
                status.createAndHoldSavepoint();//设置savepoint,
                return status;
            }
            else {
                boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
                DefaultTransactionStatus status = newTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, null);
                doBegin(transaction, definition);
                prepareSynchronization(status, definition);
                return status;
            }
        }

        if (isValidateExistingTransaction()) {
        }
        boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
        return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);
    }
protected final SuspendedResourcesHolder suspend(Object transaction) throws TransactionException {//挂起前面的事务,
        if (TransactionSynchronizationManager.isSynchronizationActive()) {//事务是活动的,
            List<TransactionSynchronization> suspendedSynchronizations = doSuspendSynchronization();
            try {
                Object suspendedResources = null;
                if (transaction != null) {
                    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);
            }
        }
    }
protected Object doSuspend(Object transaction) {
        DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
        txObject.setConnectionHolder(null);
        ConnectionHolder conHolder = (ConnectionHolder)TransactionSynchronizationManager.unbindResource(this.dataSource);
        return conHolder;
    }
方法的嵌套,事务的嵌套。(内部和外部方法的连接connection是不一样的,)
begin transation  =  TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
try {
retVal = invocation.proceedWithInvocation();
public void saveTest(String param) {
            String sql = "insert into test(num) values (?)";
            int count = jdbcTemplate.update(sql, new Object[]{param});
            begin transation  =  TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
            try {
              retVal = invocation.proceedWithInvocation();
              myService.saveTest1(param);(因为myService是jdk的动态代理,所以又会走进去),如果这里有异常,
            }
            catch (Throwable ex) {
              completeTranactionAfterThrowing(txInfo, ex);  //回滚,又把异常抛出来了,
              throw ex;//内部方法的异常跑出来之后,被外部方法捕获到了,
            }
            commit  transaction = commitTransactionAfterReturning(txInfo);//里面方法有异常之后,这个提交就执行不到了。所以内部的方法根本就没有提交,而是回滚了。
        }
        }
  catch (Throwable ex) {//内部方法的异常跑出来之后,被外部方法捕获到了,所以外部方法也没有提交,而是回滚了。(所以要在内部的方法要自己捕获异常),
   completeTranactionAfterThrowing(txInfo, ex); //事务回滚,
    throw ex;
 }
commit  transaction = commitTransactionAfterReturning(txInfo);//事务提交
原文地址:https://www.cnblogs.com/yaowen/p/11844759.html