zoukankan      html  css  js  c++  java
  • 二、GlobalTransactionalInterceptor拦截器

    所有文章

    https://www.cnblogs.com/lay2017/p/12485081.html

    正文

    上一篇文章中,我们看到被@GlobalTransactional或者@GlobalLock注解的方法,该Bean会做AOP事务增强。

    本文将阅读关于@GlobalTransactional的事务增强拦截器GlobalTransactionalInterceptor。首先,我们看一下它的UML类图

    GlobalTransactionalInterceptor设计路线只有两条,一条是spring aop的方法拦截器,另一条是seata的配置变更监听器。监听器无非就是当配置变化的时候做回调处理,GlobalTransactionalInterceptor主要是监听全局事务的关闭。

    那么,我们关注点放在对MethodInterceptor的实现上,跟进invoke方法的实现

    拦截器invoke方法

    @Override
    public Object invoke(final MethodInvocation methodInvocation) throws Throwable {
        Class<?> targetClass = methodInvocation.getThis() != null ? AopUtils.getTargetClass(methodInvocation.getThis()) : null;
        Method specificMethod = ClassUtils.getMostSpecificMethod(methodInvocation.getMethod(), targetClass);
        final Method method = BridgeMethodResolver.findBridgedMethod(specificMethod);
    
        // 拿到@GlobalTransactional注解的元数据
        final GlobalTransactional globalTransactionalAnnotation = getAnnotation(method, GlobalTransactional.class);
        // 拿到@GlobalLock注解的元数据
        final GlobalLock globalLockAnnotation = getAnnotation(method, GlobalLock.class);
        // 处理@GlobalTransactional
        if (!disable && globalTransactionalAnnotation != null) {
            return handleGlobalTransaction(methodInvocation, globalTransactionalAnnotation);
        // 处理@GlobalLock
        } else if (!disable && globalLockAnnotation != null) {
            return handleGlobalLock(methodInvocation);
        // 直接调用原始方法
        } else {
            return methodInvocation.proceed();
        }
    }

    如果事务是开启的 disable=false,那么判断方法是否有@GlobalTransactional或者@GlobalLock注解。如果有的话,那么执行对应的处理方法。如果没有,那么直接执行proceed。

    handleGlobalTransaction

    handleGlobalTransaction处理@GlobalTransactional注解,跟进该方法

    private Object handleGlobalTransaction(final MethodInvocation methodInvocation, final GlobalTransactional globalTrxAnno) throws Throwable {
        try {
            // 事务执行模板
            return transactionalTemplate.execute(new TransactionalExecutor() {
                @Override
                public Object execute() throws Throwable {
                    // 执行原始方法
                    return methodInvocation.proceed();
                }
    
                public String name() {
                    // 自定义或者格式化生成事务的名称
                    String name = globalTrxAnno.name();
                    if (!StringUtils.isNullOrEmpty(name)) {
                        return name;
                    }
                    return formatMethod(methodInvocation.getMethod());
                }
    
                @Override
                public TransactionInfo getTransactionInfo() {
                    // 将注解包装成TransactionInfo对象
                    TransactionInfo transactionInfo = new TransactionInfo();
                    transactionInfo.setTimeOut(globalTrxAnno.timeoutMills());
                    transactionInfo.setName(name());
                    Set<RollbackRule> rollbackRules = new LinkedHashSet<>();
                    for (Class<?> rbRule : globalTrxAnno.rollbackFor()) {
                        rollbackRules.add(new RollbackRule(rbRule));
                    }
                    for (String rbRule : globalTrxAnno.rollbackForClassName()) {
                        rollbackRules.add(new RollbackRule(rbRule));
                    }
                    for (Class<?> rbRule : globalTrxAnno.noRollbackFor()) {
                        rollbackRules.add(new NoRollbackRule(rbRule));
                    }
                    for (String rbRule : globalTrxAnno.noRollbackForClassName()) {
                        rollbackRules.add(new NoRollbackRule(rbRule));
                    }
                    transactionInfo.setRollbackRules(rollbackRules);
                    return transactionInfo;
                }
            });
        } catch (TransactionalExecutor.ExecutionException e) {
            // 执行异常
            TransactionalExecutor.Code code = e.getCode();
            switch (code) {
                case RollbackDone:
                    throw e.getOriginalException();
                case BeginFailure:
                    failureHandler.onBeginFailure(e.getTransaction(), e.getCause());
                    throw e.getCause();
                case CommitFailure:
                    failureHandler.onCommitFailure(e.getTransaction(), e.getCause());
                    throw e.getCause();
                case RollbackFailure:
                    failureHandler.onRollbackFailure(e.getTransaction(), e.getCause());
                    throw e.getCause();
                default:
                    throw new ShouldNeverHappenException("Unknown TransactionalExecutor.Code: " + code);
    
            }
        }
    }

    可以看到拦截器把处理@GlobalTransactional的主体执行逻辑委托给了TransactionalTemplate这个模板的execute方法,而TransactionalExecutor执行器只是提供了执行原始方法,@GlobalTransactional元数据信息,事务名称的实现。

    handleGlobalLock

    handleGlobalLock处理的是@GlobalLock的主体逻辑,比起TransactionalTemplate简单了很多。

    单纯地把所有逻辑交给GlobalLockTemplate的execute方法,执行器只是负责执行原始方法

    private Object handleGlobalLock(final MethodInvocation methodInvocation) throws Exception {
        return globalLockTemplate.execute(() -> {
            try {
                // 执行原始方法
                return methodInvocation.proceed();
            } catch (Throwable e) {
                if (e instanceof Exception) {
                    throw (Exception)e;
                } else {
                    throw new RuntimeException(e);
                }
            }
        });
    }

    总结

    GlobalTransactionalInterceptor拦截器逻辑比较简单,基本上都委托给了TransactionalTemplate和GlobalLockTemplate。拦截器只负责把对应的注解逻辑分发给对应的逻辑模板来处理。

  • 相关阅读:
    我容易么?
    意译和音译
    请教博客园高手:msn老是掉线的问题
    超市里最安全的食品
    两类人
    只要牵了手,就请不要轻易的说分手
    Palm Treo 650 .VS. Dopod P800
    强烈推荐一健康食品:紫红薯
    年底三篇
    奶奶,走好!
  • 原文地址:https://www.cnblogs.com/lay2017/p/12442951.html
Copyright © 2011-2022 走看看