zoukankan      html  css  js  c++  java
  • Seata 拦截器源码分析

    public class GlobalTransactionalInterceptor implements ConfigurationChangeListener, MethodInterceptor

      该拦截器实现了spring的接口 MethodInterceptor

    @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);
            if (specificMethod != null && !specificMethod.getDeclaringClass().equals(Object.class)) {
                final Method method = BridgeMethodResolver.findBridgedMethod(specificMethod);
                final GlobalTransactional globalTransactionalAnnotation =
                    getAnnotation(method, targetClass, GlobalTransactional.class);
                final GlobalLock globalLockAnnotation = getAnnotation(method, targetClass, GlobalLock.class);
                boolean localDisable = disable || (degradeCheck && degradeNum >= degradeCheckAllowTimes);
                if (!localDisable) {
                    if (globalTransactionalAnnotation != null) {
                        return handleGlobalTransaction(methodInvocation, globalTransactionalAnnotation);
                    } else if (globalLockAnnotation != null) {
                        return handleGlobalLock(methodInvocation);
                    }
                }
            }
            return methodInvocation.proceed();
        }

      GlobalTransactionalInterceptor # handleGlobalTransaction

    private Object handleGlobalTransaction(final MethodInvocation methodInvocation,
            final GlobalTransactional globalTrxAnno) throws Throwable {
            boolean succeed = true;
            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());
                    }

      重点是 transactionalTemplate.execute

    public Object execute(TransactionalExecutor business) throws Throwable {
            // 1 get transactionInfo
            TransactionInfo txInfo = business.getTransactionInfo();
            if (txInfo == null) {
                throw new ShouldNeverHappenException("transactionInfo does not exist");
            }
            // 1.1 get or create a transaction
            GlobalTransaction tx = GlobalTransactionContext.getCurrentOrCreate();
    
            // 1.2 Handle the Transaction propatation and the branchType
            Propagation propagation = txInfo.getPropagation();
            SuspendedResourcesHolder suspendedResourcesHolder = null;
            try {
                switch (propagation) {
                    case NOT_SUPPORTED:
                        suspendedResourcesHolder = tx.suspend(true);
                        return business.execute();
                    case REQUIRES_NEW:
                        suspendedResourcesHolder = tx.suspend(true);
                        break;
                    case SUPPORTS:
                        if (!existingTransaction()) {
                            return business.execute();
                        }
                        break;
                    case REQUIRED:
                        break;
                    case NEVER:
                        if (existingTransaction()) {
                            throw new TransactionException(
                                    String.format("Existing transaction found for transaction marked with propagation 'never',xid = %s"
                                            ,RootContext.getXID()));
                        } else {
                            return business.execute();
                        }
                    case MANDATORY:
                        if (!existingTransaction()) {
                            throw new TransactionException("No existing transaction found for transaction marked with propagation 'mandatory'");
                        }
                        break;
                    default:
                        throw new TransactionException("Not Supported Propagation:" + propagation);
                }
    
    
                try {
    
                    // 2. begin transaction
                    beginTransaction(txInfo, tx);//拿到全局XID,放到ThreadLocal里
    
                    Object rs = null;
                    try {
    
                        // Do Your Business
                        rs = business.execute();
    
                    } catch (Throwable ex) {
    
                        // 3.the needed business exception to rollback.
                        completeTransactionAfterThrowing(txInfo, tx, ex);
                        throw ex;
                    }
    
                    // 4. everything is fine, commit.
                    commitTransaction(tx);//向Seata服务端发送请求提交
    
                    return rs;
                } finally {
                    //5. clear
                    triggerAfterCompletion();
                    cleanUp();
                }
            } finally {
                tx.resume(suspendedResourcesHolder);
            }
    
        }
  • 相关阅读:
    sublime text3安装package control插件图文教程
    conda创建新环境
    常用的vscode插件安装
    数组合并组合
    内核软死锁
    Ubuntu分区格式化并挂载新增磁盘方法
    Linux如何列出svn一个文件夹下的所有文件
    C++ UTF-8和GBK相互转化
    Linux shell如何用正则表达式匹配分组数据
    如何对接jsoncpp?
  • 原文地址:https://www.cnblogs.com/juniorMa/p/15167655.html
Copyright © 2011-2022 走看看