二、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。拦截器只负责把对应的注解逻辑分发给对应的逻辑模板来处理。

原文地址:https://www.cnblogs.com/lay2017/p/12442951.html