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);
            }
    
        }
  • 相关阅读:
    C# SuperWebSocket服务端学习(二)
    C# SuperSocket服务端入门(一)
    C# SuperWebSocket服务端、客户端学习(三)
    皮尔逊相关系数和余弦相似性的关系
    各种定向方式的对比-有图
    查看Linux的CPU信息,核数等
    临时表空间
    优化临时表使用,SQL语句性能提升100倍
    Java中线程池的学习
    android面试题之六
  • 原文地址:https://www.cnblogs.com/juniorMa/p/15167655.html
Copyright © 2011-2022 走看看