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一样。

返回顶部

posted @ 2020-03-29 22:33  平淡454  阅读(179)  评论(0编辑  收藏  举报