二、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。攔截器只負責把對應的注解邏輯分發給對應的邏輯模板來處理。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM