zoukankan      html  css  js  c++  java
  • Spring 事务原理

    1,从@EnableTransactionManagement 开始入手

    2,看到它给容器注册了 TransactionManagementConfigurationSelector 类

    3,观察其 selectImports 方法,发现它给容器注册了两个bean

    4,分别是 AutoProxyRegistrar 和 ProxyTransactionManagementConfiguration ,这里重点看下  ProxyTransactionManagementConfiguration

    5,发现 proxyxxx 给容器注册了 3个bean BeanFactoryTransactionAttributeSourceAdvisor(事务增强器) ,AnnotationTransactionAttributeSource(注解事务属性),TransactionInterceptor(事务拦截器)

    6,观察 AnnotationTransactionAttributeSource ,发现它会解析@Transactional 的属性

    #SpringTransactionAnnotationParser 类
    protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) {
            RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();
            Propagation propagation = attributes.getEnum("propagation");
            rbta.setPropagationBehavior(propagation.value());
            Isolation isolation = attributes.getEnum("isolation");
            rbta.setIsolationLevel(isolation.value());
            rbta.setTimeout(attributes.getNumber("timeout").intValue());
            rbta.setReadOnly(attributes.getBoolean("readOnly"));
            rbta.setQualifier(attributes.getString("value"));
            ArrayList<RollbackRuleAttribute> rollBackRules = new ArrayList<>();
            Class<?>[] rbf = attributes.getClassArray("rollbackFor");
            for (Class<?> rbRule : rbf) {
                RollbackRuleAttribute rule = new RollbackRuleAttribute(rbRule);
                rollBackRules.add(rule);
            }
            String[] rbfc = attributes.getStringArray("rollbackForClassName");
            for (String rbRule : rbfc) {
                RollbackRuleAttribute rule = new RollbackRuleAttribute(rbRule);
                rollBackRules.add(rule);
            }
            Class<?>[] nrbf = attributes.getClassArray("noRollbackFor");
            for (Class<?> rbRule : nrbf) {
                NoRollbackRuleAttribute rule = new NoRollbackRuleAttribute(rbRule);
                rollBackRules.add(rule);
            }
            String[] nrbfc = attributes.getStringArray("noRollbackForClassName");
            for (String rbRule : nrbfc) {
                NoRollbackRuleAttribute rule = new NoRollbackRuleAttribute(rbRule);
                rollBackRules.add(rule);
            }
            rbta.getRollbackRules().addAll(rollBackRules);
            return rbta;
        }

     7,再看 TransactionInterceptor ,发现它实现了 MethodInterceptor 也就是目标方法被调用的时候,实际执行的是 TransactionInterceptor  的 invoke 方法

    8,观察 invoke 方法 ,调用了 invokeWithinTransaction 方法

    protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
                final InvocationCallback invocation) throws Throwable {
    
            // If the transaction attribute is null, the method is non-transactional.
            //拿到注解上的属性
            TransactionAttributeSource tas = getTransactionAttributeSource();
            final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
            //拿到事务管理器
            final PlatformTransactionManager tm = determineTransactionManager(txAttr);
            final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
    
            if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
                // Standard transaction demarcation with getTransaction and commit/rollback calls.
                TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
                Object retVal = null;
                try {
                    // This is an around advice: Invoke the next interceptor in the chain.
                    // This will normally result in a target object being invoked.
                    //执行目标方法,得到结果
                    retVal = invocation.proceedWithInvocation();
                }
                catch (Throwable ex) {
                    // target invocation exception
                    //目标方法发生异常,利用事务管理器进行回滚
                    completeTransactionAfterThrowing(txInfo, ex);
                    throw ex;
                }
                finally {
                    //收尾工作
                    cleanupTransactionInfo(txInfo);
                }
                //提交事务,利用事务管理器进行提交
                commitTransactionAfterReturning(txInfo);
                return retVal;
            }
    
            else {
                final ThrowableHolder throwableHolder = new ThrowableHolder();
    
                // It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
                try {
                    Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr, status -> {
                        TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
                        try {
                            return invocation.proceedWithInvocation();
                        }
                        catch (Throwable ex) {
                            if (txAttr.rollbackOn(ex)) {
                                // A RuntimeException: will lead to a rollback.
                                if (ex instanceof RuntimeException) {
                                    throw (RuntimeException) ex;
                                }
                                else {
                                    throw new ThrowableHolderException(ex);
                                }
                            }
                            else {
                                // A normal return value: will lead to a commit.
                                throwableHolder.throwable = ex;
                                return null;
                            }
                        }
                        finally {
                            cleanupTransactionInfo(txInfo);
                        }
                    });
    
                    // Check result state: It might indicate a Throwable to rethrow.
                    if (throwableHolder.throwable != null) {
                        throw throwableHolder.throwable;
                    }
                    return result;
                }
                catch (ThrowableHolderException ex) {
                    throw ex.getCause();
                }
                catch (TransactionSystemException ex2) {
                    if (throwableHolder.throwable != null) {
                        logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
                        ex2.initApplicationException(throwableHolder.throwable);
                    }
                    throw ex2;
                }
                catch (Throwable ex2) {
                    if (throwableHolder.throwable != null) {
                        logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
                    }
                    throw ex2;
                }
            }
        }

    9,jdbc的事务开启,提交和回滚,实际都是对 Connection 的操作 

    //开启事务
    if(cnn.getAutoCommit()){
        cnn.setAutoCommit(false);
    }
    //提交事务
    if(!cnn.getAutoCommit()){
        cnn.commit();
    }
    //回滚事务
    if(!cnn.getAutoCommit()){
        cnn.rollback();
    }
  • 相关阅读:
    hdu 1455 N个短木棒 拼成长度相等的几根长木棒 (DFS)
    hdu 1181 以b开头m结尾的咒语 (DFS)
    hdu 1258 从n个数中找和为t的组合 (DFS)
    hdu 4707 仓鼠 记录深度 (BFS)
    LightOJ 1140 How Many Zeroes? (数位DP)
    HDU 3709 Balanced Number (数位DP)
    HDU 3652 B-number (数位DP)
    HDU 5900 QSC and Master (区间DP)
    HDU 5901 Count primes (模板题)
    CodeForces 712C Memory and De-Evolution (贪心+暴力)
  • 原文地址:https://www.cnblogs.com/dongma/p/10048251.html
Copyright © 2011-2022 走看看