• 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();
    }
  • 相关阅读:
    WinForm开发中几种找控件的方法
    C#读取Excel文件时提示:无法指出的错误
    数据库中取随机记录的方法
    C#写数据到Excel
    从数据库导出数据到word、excel、.txt
    Telerik RadTreeView查寻值的方法
    如何导出WinForm 控件界面的矢量图
    简单数据缓存类(c#)
    Windows Installer 清理实用工具说明
    硬盘安装Win7全攻略
  • 原文地址:https://www.cnblogs.com/dongma/p/10048251.html
Copyright © 2020-2023  润新知