zoukankan      html  css  js  c++  java
  • 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);//事务提交
  • 相关阅读:
    有关tensorflow一些问题
    一个完整openlayer的例子,包括marker,popup等
    OpenLayers中的Layer概念和实践--Openlayers调用WMS服务
    MapInfo格式转arggis格式
    arcgis for server 登陆manager失败解决办法
    1752:鸡兔同笼(2.1)
    1749:数字方格(2.1)
    08:石头剪刀布(1.6)
    c++中的243、251、250错误原因
    05:年龄与疾病(1.6)
  • 原文地址:https://www.cnblogs.com/yaowen/p/11844759.html
Copyright © 2011-2022 走看看