• spring事务


    事务的四个特性

    1、原子性
    2、一致性
    原子性和一致性紧密联系,区别是什么?
    举例:A给B转100块钱,需要两步:
    1、A = A-100
    2、B = B+100
    原子性指把这两步放入到一个事务中,要么都执行成功,要么都失败。
    一致性指的是在写代码的时候,写了1,就一定要写2,否则数据出现不一致的情况。
    3、持久性:事务一旦提交,会写入到持久化存储器中,就算系统崩溃了,数据也能找回。
    4、隔离性:多个事务处理相同数据的时候,他们之间应该是独立的,不能互相影响。

    spring可配置事务的属性有哪些

    传播行为
    事务超时
    回滚规则
    隔离规则:定义了一个事务可以看到另一个事务中的哪些数据
    是否只读

    事务传播行为

    spring支持7中事务传播行为,A方法调用B方法:
    1、A有事务,B加入A事务,A无事务,B无事务运行
    2、A有事务,B加入,A无事务,B开启新事务
    3、A有事务,A事务挂起,B开启自己事务:两个事务互相独立
    4、A有事务,B开启新事务,嵌套到A中:B事务失败不会影响A,A事务失败会把B也回滚。
    5、A有事务,B加入,A无事务,B抛出异常
    6、A有事务,挂起,B无事务运行
    7、A有事务,抛异常

    事务不生效的几种可能

    1、数据库引擎不支持事务。
    innodb支持事务,myisam不支持事务

    2、事务所在的类必须被spring容器所管理

    3、@Transaction注解的方法必须为public

    4、自身调用
    spring事务传播是指两个方法是在不同的类中,如果两个方法属于同一个类,那么事务的传播配置就会失效。

    @Service
    public class OrderServiceImpl implements OrderService {
    
        @Transactional
        public void update(Order order) {
            this.updateOrder(order);
        }
    
        @Transactional(propagation = Propagation.REQUIRES_NEW)
        public void updateOrder(Order order) {
            // update order
        }
    
    }
    

    上面代码,updateOrder方法的事务配置是不会生效的,
    原因:spring声明事务是通过spring aop实现的,spring aop会生成一个代理类,在代理类中执行事务管理逻辑,上面代码中update方法调用this.updateOrder方法不是通过代理类,所以updateOrder方法事务没有生效。

    可以通过aop代理类调用updateOrder方法。

    首先开启该功能

    <aop:aspectj-autoproxy expose-proxy="true"/>
    

    this.updateOrder();-----------修改为--------->AopContext.currentProxy()).updateOrder();

    5、异常没有正确抛出

    public class OrderServiceImpl implements OrderService {
    
        @Transactional
        public void updateOrder(Order order) {
            try {
                // update order
            } catch {
    //这里没有抛出异常
            }
        }
    
    }
    
    public class OrderServiceImpl implements OrderService {
    
        @Transactional
        public void updateOrder(Order order) {
            try {
                // update order
            } catch {//这里必须改成运行时异常
                throw new Exception("更新错误");
            } 
        }
    
    }
    

    隔离级别

    spring的隔离级别有5中:
    1、采用数据库设置的隔离级别
    2、对应数据库的uncommited
    3、commited
    4、repeatable
    5、串行

    只读

    当一个事务中有多条查询语句的时候,开启只读属性,则数据库会自动进行sql优化

    回滚

    默认情况下,遇到运行时异常事务会回滚,这里可以指定异常类型,还可以指定哪些异常不回滚

    编程式事务

    声明式事务是spring通过注解实现,提前定义好的一些。编程式事务则是在代码中自己进行事务管理,缺点是代码侵入,优点是可以自己管理事务。

    使用方式

    首先xml中配置

    <tx:annotation-driven transaction-manager="transactionManager"/>
    
        <bean id="sessionFactory" 
                class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> 
            <property name="configLocation" value="classpath:hibernate.cfg.xml" /> 
            <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" />
        </bean> 
    
        <!-- 定义事务管理器(声明式的事务) --> 
        <bean id="transactionManager"
            class="org.springframework.orm.hibernate3.HibernateTransactionManager">
            <property name="sessionFactory" ref="sessionFactory" />
        </bean>
    

    然后在相关方法中加入注解即可

    返回顶部

    初始化

    在spring ioc初始化过程中,遇到自定义标签tx:annotation-driven,通过事务命名空间找到事务自定义标签解析器,执行该方法解析事务相关标签

    //TxNamespaceHandler
    @Override
    public void init() {
        registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser());
        registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
        registerBeanDefinitionParser("jta-transaction-manager", new JtaTransactionManagerBeanDefinitionParser());
    }
    
    //AnnotationDrivenBeanDefinitionParser
    @Override
        public BeanDefinition parse(Element element, ParserContext parserContext) {
            registerTransactionalEventListenerFactory(parserContext);
            String mode = element.getAttribute("mode");
            /***
             * 对于mode属性的判断
             * 如果我们需要使用AspectJ的方式进行事务切入(Spring中的事务是以AOP为基础的),那么可以使用这样的配置:
             * <tx:annotation-driven transaction-manager="transactionManager" mode="aspectj"/>
             */
            if ("aspectj".equals(mode)) {
                // mode="aspectj"
                registerTransactionAspect(element, parserContext);
            }
            else {//正常情况进入这个分支
                // mode="proxy"
                AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
            }
            return null;
        }
    
    public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
            //注册代理类生成器
            AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);//入口1
    
            String txAdvisorBeanName = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME;
            if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) {
                Object eleSource = parserContext.extractSource(element);
    
                // 创建AnnotationTransactionAttributeSource类型的Bean,该类型bean代表pointcut
                RootBeanDefinition sourceDef = new RootBeanDefinition(
                        "org.springframework.transaction.annotation.AnnotationTransactionAttributeSource");
                sourceDef.setSource(eleSource);
                sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
                String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);
    
                // 创建TransactionInterceptor类型的Bean,该类型bean代表advice
                RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class);
                interceptorDef.setSource(eleSource);
                interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
                registerTransactionManager(element, interceptorDef);
                interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
                String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);
    
                // 创建BeanFactoryTransactionAttributeSourceAdvisor实例bean
                RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);
                advisorDef.setSource(eleSource);
                advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
                //将上面创建的AnnotationTransactionAttributeSource和TransactionInterceptor封装到BeanFactoryTransactionAttributeSourceAdvisor中
             //将advice和pointcut封装到advisor中
                advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
                advisorDef.getPropertyValues().add("adviceBeanName", interceptorName);
                if (element.hasAttribute("order")) {
                    advisorDef.getPropertyValues().add("order", element.getAttribute("order"));
                }
                parserContext.getRegistry().registerBeanDefinition(txAdvisorBeanName, advisorDef);
                //将上面三个Bean注册进IOC中
                CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource);
                compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName));
                compositeDef.addNestedComponent(new BeanComponentDefinition(interceptorDef, interceptorName));
                compositeDef.addNestedComponent(new BeanComponentDefinition(advisorDef, txAdvisorBeanName));
                parserContext.registerComponent(compositeDef);
            }
        }
    
    //AopNamespaceUtils
        public static void registerAutoProxyCreatorIfNecessary(ParserContext parserContext, Element sourceElement) {
            BeanDefinition beanDefinition = AopConfigUtils.registerAutoProxyCreatorIfNecessary(parserContext.getRegistry(), parserContext.extractSource(sourceElement));
            //处理proxy-target-class与expose-proxy属性
            useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);//入口
            registerComponentIfNecessary(beanDefinition, parserContext);
        }
    
    
        private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, Element sourceElement) {
            if (sourceElement != null) {
                boolean proxyTargetClass = Boolean.valueOf(sourceElement.getAttribute("proxy-target-class"));
                if (proxyTargetClass) {
                    AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
                }
    
                boolean exposeProxy = Boolean.valueOf(sourceElement.getAttribute("expose-proxy"));
                if (exposeProxy) {
                    AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);//入口
                }
            }
    
        }
    
    
    
        public static void forceAutoProxyCreatorToExposeProxy(BeanDefinitionRegistry registry) {
            if (registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) {
                BeanDefinition definition = registry.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator");
                definition.getPropertyValues().add("exposeProxy", Boolean.TRUE);
            }
    
        }
    
    
    1. spring容器在初始化过程中,遇到spring开启事务的标签tx:annotation-driven,会通过命名空间找到命名空间处理器TxNamespaceHandler,该处理器的初始化方法中给spring事务的根标签绑定了一个标签解析器AnnotationDrivenBeanDefinitionParser,然后调用解析器的parse方法对事务标签进行解析
    2. 注册了代理类生成器
      • 创建class为InfrastructureAdvisorAutoProxyCreator的bean,该bean即代理类生产器
      • 设置proxy-target-class与expose-proxy属性:即将这两个属性封装到InfrastructureAdvisorAutoProxyCreator中
    3. 创建三种类型的bean,beanClass分别为AnnotationTransactionAttributeSource、TransactionInterceptor、BeanFactoryTransactionAttributeSourceAdvisor,他们分别封装了相应的pointcut、advice、advisor,同时将前两个bean封装到第三个bean里。
      然后将这三种类型的bean都加入到spring容器中。

    返回顶部

    getBean时通过BeanPostProcessor回调生成代理类

    上面流程会将需要事务增强的方法都封装到advisor中,接下来是getBean的时候,根据BeanPostProcessor回调机制调用,
    根据要创建的bean去advisor中去匹配,如果匹配成功,则创建代理类。

    //AbstractAutoProxyCreator
    @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            if (bean != null) {
                Object cacheKey = getCacheKey(bean.getClass(), beanName);
                if (this.earlyProxyReferences.remove(cacheKey) != bean) {
                    return wrapIfNecessary(bean, beanName, cacheKey);
                }
            }
            return bean;
        }
        protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
            //几种不需要代理的情况,直接返回
            if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
                return bean;
            }
            if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
                return bean;
            }
            if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return bean;
            }
    
            // 这里是主要验证的地方,传入Bean的class与beanName去判断此Bean有哪些Advisor
           //获取匹配的advisor,然后转换成拦截器链条(放入一个list中)
    //入口
            Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
            // 如果有相应的advisor被找到,则用advisor与此bean做一个动态代理,将这两个的信息
            // 放入代理类中进行代理
            if (specificInterceptors != DO_NOT_PROXY) {
                this.advisedBeans.put(cacheKey, Boolean.TRUE);
                // 创建代理的地方
                Object proxy = createProxy(
                        bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
                this.proxyTypes.put(cacheKey, proxy.getClass());
                // 返回代理对象
                return proxy;
            }
            // 如果此Bean没有一个Advisor匹配,将返回null也就是DO_NOT_PROXY
            // 也就是会走到这一步,将其cacheKey,false存入Map中
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            // 不代理直接返回原bean
            return bean;
        }
    
    //AbstractAdvisorAutoProxyCreator
    @Override
        protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
            List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
            if (advisors.isEmpty()) {
                return DO_NOT_PROXY;
            }
            return advisors.toArray();
        }
    
    protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
            //获取所有候选advisor
            List<Advisor> candidateAdvisors = findCandidateAdvisors();//入口1
            //获取可用advisor
            //入口2
            List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
            extendAdvisors(eligibleAdvisors);
            if (!eligibleAdvisors.isEmpty()) {
                eligibleAdvisors = sortAdvisors(eligibleAdvisors);
            }
            return eligibleAdvisors;
        }
    
    //AbstractAdvisorAutoProxyCreator
    protected List<Advisor> findCandidateAdvisors() {
            return this.advisorRetrievalHelper.findAdvisorBeans();
        }
    
    ##BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans:将容器初始化阶段装进去的advisor取出来
    public List<Advisor> findAdvisorBeans() {
            String[] advisorNames = this.cachedAdvisorBeanNames;
            if (advisorNames == null) {
                advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                        this.beanFactory, Advisor.class, true, false);
                this.cachedAdvisorBeanNames = advisorNames;
            }
            if (advisorNames.length == 0) {
                return new ArrayList<Advisor>();
            }
    
            List<Advisor> advisors = new ArrayList<Advisor>();
            for (String name : advisorNames) {
                if (isEligibleBean(name)) {
                    advisors.add(this.beanFactory.getBean(name, Advisor.class));
                }
            }
            return advisors;
        }
    
    /AbstractAdvisorAutoProxyCreator
        protected List<Advisor> findAdvisorsThatCanApply(
                List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
    
            ProxyCreationContext.setCurrentProxiedBeanName(beanName);
            try {
                return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
            }
            finally {
                ProxyCreationContext.setCurrentProxiedBeanName(null);
            }
        }
    //    AopUtils.findAdvisorsThatCanApply:
        public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
            if (candidateAdvisors.isEmpty()) {
                return candidateAdvisors;
            }
            List<Advisor> eligibleAdvisors = new LinkedList<Advisor>();
            //IntroductionAdvisor为引介增强
            for (Advisor candidate : candidateAdvisors) {
                //暂不考虑引介增强,这里一个都不会进入
                if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
                    eligibleAdvisors.add(candidate);
                }
            }
            boolean hasIntroductions = !eligibleAdvisors.isEmpty();
            for (Advisor candidate : candidateAdvisors) {
                if (candidate instanceof IntroductionAdvisor) {
                    //暂不考虑引介增强,这里一个都不会进入
                    continue;
                }
                if (canApply(candidate, clazz, hasIntroductions)) {//入口
                    eligibleAdvisors.add(candidate);
                }
            }
            return eligibleAdvisors;
        }
    
    public static boolean canApply(Advisor advisor, Class<?> targetClass) {
            return canApply(advisor, targetClass, false);
        }
        public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
            //暂不考虑引介增强,这里一个都不会进入
            if (advisor instanceof IntroductionAdvisor) {
                return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
            }
            else if (advisor instanceof PointcutAdvisor) {//切点
                PointcutAdvisor pca = (PointcutAdvisor) advisor;
                return canApply(pca.getPointcut(), targetClass, hasIntroductions);//入口
            }
            else {//通知类型的advisor,不需要匹配,直接返回
                // It doesn't have a pointcut so we assume it applies.
                return true;
            }
        }
    
    public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
            Assert.notNull(pc, "Pointcut must not be null");
            if (!pc.getClassFilter().matches(targetClass)) {
                return false;
            }
    
            //此时的pc表示TransactionAttributeSourcePointcut
            //pc.getMethodMatcher()返回的正是自身(this)
            MethodMatcher methodMatcher = pc.getMethodMatcher();
            if (methodMatcher == MethodMatcher.TRUE) {
                return true;
            }
    
            IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
            if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
                introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
            }
            //对于事物的配置不仅仅局限于在函数上配置,我们都知道,在类或接口上的配置可以延续到类中的每个函数
            //获取对应类的所有接口
            Set<Class<?>> classes = new LinkedHashSet<Class<?>>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
            classes.add(targetClass);
            //对类进行遍历
            for (Class<?> clazz : classes) {
                //反射获取类中所有的方法
                Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
                for (Method method : methods) {
                    //对类和方法进行增强器匹配
                    if ((introductionAwareMethodMatcher != null &&
                            introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) ||
                            methodMatcher.matches(method, targetClass)) {//入口  这个匹配就是找@Transaction注解的过程
                        return true;
                    }
                }
            }
            return false;
        }
    
    //    TransactionAttributeSourcePointcut.matches
        public boolean matches(Method method, Class<?> targetClass) {
            if (targetClass != null && TransactionalProxy.class.isAssignableFrom(targetClass)) {
                return false;
            } else {
                TransactionAttributeSource tas = this.getTransactionAttributeSource();
                return tas == null || tas.getTransactionAttribute(method, targetClass) != null;
            }
        }
    
    //AbstractFallbackTransactionAttributeSource
     @Override
        public TransactionAttribute getTransactionAttribute(Method method, Class<?> targetClass) {
            if (method.getDeclaringClass() == Object.class) {
                return null;
            }
    
            // First, see if we have a cached value.
            Object cacheKey = getCacheKey(method, targetClass);
            TransactionAttribute cached = this.attributeCache.get(cacheKey);
            if (cached != null) {
                // Value will either be canonical value indicating there is no transaction attribute,
                // or an actual transaction attribute.
                if (cached == NULL_TRANSACTION_ATTRIBUTE) {
                    return null;
                }
                else {
                    return cached;
                }
            }
            else {
                // We need to work it out.
                TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);//入口
                // Put it in the cache.
                if (txAttr == null) {
                    this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);
                }
                else {
                    String methodIdentification = ClassUtils.getQualifiedMethodName(method, targetClass);
                    if (txAttr instanceof DefaultTransactionAttribute) {
                        ((DefaultTransactionAttribute) txAttr).setDescriptor(methodIdentification);
                    }
                    if (logger.isDebugEnabled()) {
                        logger.debug("Adding transactional method '" + methodIdentification + "' with attribute: " + txAttr);
                    }
                    this.attributeCache.put(cacheKey, txAttr);
                }
                return txAttr;
            }
        }
        @Nullable
        protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
            if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
                return null;
            }
    
            /**
             * 如果方法中存在事务属性,则使用方法上的属性,否则使用方法所在的类上的属性,
             * 如果方法所在类的属性上还是没有搜寻到对应的事务属性,那么在搜寻接口中的方法,
             * 再没有的话,最后尝试搜寻接口的类上面的声明
             */
    
            // method代表接口中的方法,specificMethod代表实现类中的方法
            Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);
    
            // 查看方法中是否存在事务声明
            TransactionAttribute txAttr = findTransactionAttribute(specificMethod);//入口
            if (txAttr != null) {
                return txAttr;
            }
    
            // 查看方法所在类中是否存在事务声明
            txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());//入口
            if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
                return txAttr;
            }
    
            // 如果存在接口,则到接口中去寻找
            if (specificMethod != method) {
                // 查找接口方法
                txAttr = findTransactionAttribute(method);
                if (txAttr != null) {
                    return txAttr;
                }
                // 到接口中的类中去寻找
                txAttr = findTransactionAttribute(method.getDeclaringClass());
                if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
                    return txAttr;
                }
            }
    
            return null;
        }
    
    //AnnotationTransactionAttributeSource
    @Override
        protected TransactionAttribute findTransactionAttribute(Method method) {
            return determineTransactionAttribute(method);
        }
        protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
            if (element.getAnnotations().length > 0) {
                for (TransactionAnnotationParser annotationParser : this.annotationParsers) {
                    TransactionAttribute attr = annotationParser.parseTransactionAnnotation(element);
                    if (attr != null) {
                        return attr;
                    }
                }
            }
            return null;
        }
        @Override
        @Nullable
        public TransactionAttribute parseTransactionAnnotation(AnnotatedElement ae) {
            AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
                    ae, Transactional.class, false, false);
            if (attributes != null) {
                return parseTransactionAnnotation(attributes);
            }
            else {
                return null;
            }
        }
        protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) {
            /***
             * 首先会判断当前的类是否含有 Transactional注解,这是事务属性的基础,
             * 当然如果有的话会继续调用parseTransactionAnnotation 方法解析详细的属性。
             */
            RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();
            Propagation propagation = attributes.getEnum("propagation");
            // 解析propagation
            rbta.setPropagationBehavior(propagation.value());
            Isolation isolation = attributes.getEnum("isolation");
            // 解析isolation
            rbta.setIsolationLevel(isolation.value());
            // 解析timeout
            rbta.setTimeout(attributes.getNumber("timeout").intValue());
            // 解析readOnly
            rbta.setReadOnly(attributes.getBoolean("readOnly"));
            // 解析value
            rbta.setQualifier(attributes.getString("value"));
            ArrayList<RollbackRuleAttribute> rollBackRules = new ArrayList<>();
            // 解析rollbackFor
            Class<?>[] rbf = attributes.getClassArray("rollbackFor");
            for (Class<?> rbRule : rbf) {
                RollbackRuleAttribute rule = new RollbackRuleAttribute(rbRule);
                rollBackRules.add(rule);
            }
            // 解析rollbackForClassName
            String[] rbfc = attributes.getStringArray("rollbackForClassName");
            for (String rbRule : rbfc) {
                RollbackRuleAttribute rule = new RollbackRuleAttribute(rbRule);
                rollBackRules.add(rule);
            }
            // 解析noRollbackFor
            Class<?>[] nrbf = attributes.getClassArray("noRollbackFor");
            for (Class<?> rbRule : nrbf) {
                NoRollbackRuleAttribute rule = new NoRollbackRuleAttribute(rbRule);
                rollBackRules.add(rule);
            }
            // 解析noRollbackForClassName
            String[] nrbfc = attributes.getStringArray("noRollbackForClassName");
            for (String rbRule : nrbfc) {
                NoRollbackRuleAttribute rule = new NoRollbackRuleAttribute(rbRule);
                rollBackRules.add(rule);
            }
            rbta.getRollbackRules().addAll(rollBackRules);
            return rbta;
        }
    
    1. 首先获取所有class为Advisor的bean
    2. 遍历上面获取到的所有的advisor,如果通知类型是AnnotationTransactionAttributeSource,则代表是开启了事务,则开始在bean上搜索@Transaction注解。
      • 如果方法中存在事务属性,则使用方法上的属性,否则使用方法所在的类上的属性,
      • 如果方法所在类的属性上还是没有搜寻到对应的事务属性,那么在搜寻接口中的方法,
    3. 如果找到@Transaction注解,还要继续解析事务的其他属性
    4. 如果上面过程中匹配到了增强器,则创建代理。将所有的增强器封装成一个链表集合(事务就属于一种增强器)

    代理类生成、执行invoke和aop一样。

    返回顶部

  • 相关阅读:
    jQuery中删除方法empty(),remove()和detach()的区别
    怎么设置font awesome图标的大小?
    什么是回调函数?
    MIP开发教程(三) 使用MIPCLI工具调试组件
    MIP开发教程(一) MIPCLI工具安装与环境部署
    MIP 2016年终总结
    MIP开发教程(二) 使用MIPCLI工具调试MIP网页
    VIP站长大会(北京站)常见问题解答
    MIP开发常见问题解答
    CMS模板应用调研问卷
  • 原文地址:https://www.cnblogs.com/yanhui007/p/12595553.html
Copyright © 2020-2023  润新知