美文网首页
【Spring源码】声明式事务源码分析

【Spring源码】声明式事务源码分析

作者: RalapHao | 来源:发表于2019-04-12 14:46 被阅读0次

    环境搭建

    1. 加入相关依赖
      c3p0、spring-jdbc、mysql-connector-java、spring-context
      注意:spring-jdbc和spring-context 的版本尽量保持一致(不一致可能引起jar包冲突,报错信息 org.springframework.util.ClassUtils.getQualifiedMethodName(Ljava/lang/reflect/Method;Ljava/lang/Clas)
    2. 配置数据源DataSource
      ComboPooledDataSource dataSource = new ComboPooledDataSource();
      dataSource.setUser("xxx");
      dataSource.setPassword("xxx");
      dataSource.setDriverClass("com.mysql.jdbc.Driver");
      dataSource.setJdbcUrl("jdbc:mysql://xxxx:3306/test?useUnicode=true&characterEncoding=utf8");
    3. 配置JdbcTemplate
      JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource());//可以直接调用方法获取数据源,这里和容器中的DataSource一致(Spring的机制)
    4. 配置事务管理器TransactionManager
      DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(dataSource());
    5. 开启事务
      @EnableTransactionManagement

    原理

    1. @EnableTransactionManagement
      开启事务,注入TransactionManagementConfigurationSelector组件
    2. TransactionManagementConfigurationSelector
     protected String[] selectImports(AdviceMode adviceMode) {
            //adviceMode默认为AdviceMode mode() default AdviceMode.PROXY
            //所以重点关注AutoProxyRegistrar、ProxyTransactionManagementConfiguration
            switch(adviceMode) {
            case PROXY:
                return new String[]{AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()};
            case ASPECTJ:
                return new String[]{"org.springframework.transaction.aspectj.AspectJTransactionManagementConfiguration"};
            default:
                return null;
            }
        }
    
    AutoProxyRegistrar相关
        @Override
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
            boolean candidateFound = false;
            Set<String> annoTypes = importingClassMetadata.getAnnotationTypes();
            for (String annoType : annoTypes) {
                AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annoType);
                Object mode = candidate.get("mode");
                Object proxyTargetClass = candidate.get("proxyTargetClass");
                if (mode != null && proxyTargetClass != null && AdviceMode.class == mode.getClass() &&
                        Boolean.class == proxyTargetClass.getClass()) {
                    candidateFound = true;
                    if (mode == AdviceMode.PROXY) {
                                            //注册自动代理创建器
                        AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
                        if ((Boolean) proxyTargetClass) {
                            AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
                            return;
                        }
                    }
                }
            }
    ...
        }
    
    //这里和AOP模式相,AOP为容器注入AnnotationAwareAspectJAutoProxyCreator,
    //事务这里注入的是InfrastructureAdvisorAutoProxyCreator(后置处理器)
    //InfrastructureAdvisorAutoProxyCreator主要是在使用后置处理器在对象创建后,结合增强器包装对象,在代对象执行方法通过拦截器链进行调用
    private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
            Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
            if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
                BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
                if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
                    int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
                    int requiredPriority = findPriorityForClass(cls);
                    if (currentPriority < requiredPriority) {
                        apcDefinition.setBeanClassName(cls.getName());
                    }
                }
                return null;
            }
            RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
            beanDefinition.setSource(source);
            beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
            beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
            registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
            return beanDefinition;
        }
    
    ProxyTransactionManagementConfiguration(为事务注入增强器)
    
    //注入事务增强器
    @Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
        @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
        public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
            BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
            advisor.setTransactionAttributeSource(transactionAttributeSource());
            advisor.setAdvice(transactionInterceptor());
            advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
            return advisor;
        }
    
            //注入事务属相相关属性配置(SpringTransactionAnnotationParser、JtaTransactionAnnotationParser、Ejb3TransactionAnnotationParser)
        @Bean
        @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
        public TransactionAttributeSource transactionAttributeSource() {
            return new AnnotationTransactionAttributeSource();
        }
            //事务拦截器(MethodInterceptor)
        @Bean
        @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
        public TransactionInterceptor transactionInterceptor() {
            TransactionInterceptor interceptor = new TransactionInterceptor();
                    //设置事务属性信息
            interceptor.setTransactionAttributeSource(transactionAttributeSource());
            if (this.txManager != null) {
                            //设置事务管理信息
                interceptor.setTransactionManager(this.txManager);
            }
            return interceptor;
        }
    
          
        @Override
        public Object invoke(final MethodInvocation invocation) throws Throwable {
            // Work out the target class: may be {@code null}.
            // The TransactionAttributeSource should be passed the target class
            // as well as the method, which may be from an interface.
            Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
    
            // Adapt to TransactionAspectSupport's invokeWithinTransaction...
            return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
                @Override
                public Object proceedWithInvocation() throws Throwable {
                    return invocation.proceed();
                }
            });
        }
        
    //目标方法执行前,执行拦截器链
        protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation)
                throws Throwable {
                    //获取属性信息
            // If the transaction attribute is null, the method is non-transactional.
            final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
                    //获取管理信息
            final PlatformTransactionManager tm = determineTransactionManager(txAttr);
                   //获取目标方法
            final String joinpointIdentification = methodIdentification(method, targetClass);
    
            if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
                // Standard transaction demarcation with getTransaction and commit/rollback calls.
                TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
                Object retVal = null;
                try {
                                    //执行方法链(包括目标方法)
                    // This is an around advice: Invoke the next interceptor in the chain.
                    // This will normally result in a target object being invoked.
                    retVal = invocation.proceedWithInvocation();
                }
                catch (Throwable ex) {
                                    //异常回滚
                    // target invocation exception
                    completeTransactionAfterThrowing(txInfo, ex);
                    throw ex;
                }
                finally {
                    cleanupTransactionInfo(txInfo);
                }
                            //提交事务
                commitTransactionAfterReturning(txInfo);
                return retVal;
            }
    
            else {
                // It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
                try {
                    Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr,
                            new TransactionCallback<Object>() {
                                @Override
                                public Object doInTransaction(TransactionStatus status) {
                                    TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
                                    try {
                                        return invocation.proceedWithInvocation();
                                    }
                                    catch (Throwable ex) {
                                        if (txAttr.rollbackOn(ex)) {
                                            // A RuntimeException: will lead to a rollback.
                                            if (ex instanceof RuntimeException) {
                                                throw (RuntimeException) ex;
                                            }
                                            else {
                                                throw new ThrowableHolderException(ex);
                                            }
                                        }
                                        else {
                                            // A normal return value: will lead to a commit.
                                            return new ThrowableHolder(ex);
                                        }
                                    }
                                    finally {
                                        cleanupTransactionInfo(txInfo);
                                    }
                                }
                            });
    
                    // Check result: It might indicate a Throwable to rethrow.
                    if (result instanceof ThrowableHolder) {
                        throw ((ThrowableHolder) result).getThrowable();
                    }
                    else {
                        return result;
                    }
                }
                catch (ThrowableHolderException ex) {
                    throw ex.getCause();
                }
            }
        }
            //获取事务管理信息
        protected PlatformTransactionManager determineTransactionManager(TransactionAttribute txAttr) {
            // Do not attempt to lookup tx manager if no tx attributes are set
            if (txAttr == null || this.beanFactory == null) {
                            //事务信息不存存在,返回默认事务管理器
                return getTransactionManager();
            }
                    //是否标记@Qualifier
            String qualifier = txAttr.getQualifier();
            if (StringUtils.hasText(qualifier)) {
                            //指定@Qualifier
                return determineQualifiedTransactionManager(qualifier);
            }
            else if (StringUtils.hasText(this.transactionManagerBeanName)) {
                            //根据指定的transactionManagerBeanName进行设置
                return determineQualifiedTransactionManager(this.transactionManagerBeanName);
            }
            else {
                             //默认配置
                PlatformTransactionManager defaultTransactionManager = getTransactionManager();
                if (defaultTransactionManager == null) {
                    defaultTransactionManager = this.beanFactory.getBean(PlatformTransactionManager.class);
                    this.transactionManagerCache.putIfAbsent(
                            DEFAULT_TRANSACTION_MANAGER_KEY, defaultTransactionManager);
                }
                return defaultTransactionManager;
            }
        }
    

    总结

    声明式事务主要用到的模式是AOP,通过后置处理器将对象代理,通过ProxyTransactionManagementConfiguration喂食物注入增强器、拦截器,最后通过拦截器封装TransationInfo信息(包括事务信息、事务管理器信息),最后执行拦截器链(包含目标方法),通过异常判事务的回滚与提交

    相关文章

      网友评论

          本文标题:【Spring源码】声明式事务源码分析

          本文链接:https://www.haomeiwen.com/subject/cbwqwqtx.html