zoukankan      html  css  js  c++  java
  • @Transactional实现事务管理原理

    @Transactional注解事务管理的底层实现脉络,就是使用拦截器。它就是TransactionInterceptor。

    TransactionInterceptor是继承于TransactionAspectSupport的拦截器,拦截器的原理在这里就不细说了。被@Transactional注解的方法会被TransactionInterceptor拦截,

    其invoke方法被调用,最终会调用父类TransactionAspectSupport的invokeWithinTransaction方法。

        public Object invoke(MethodInvocation invocation) throws Throwable {
            // Work out the target class: may be {@code null}.
            // The TransactionAttributeSource should be passed the target class
            // as well as the method, which may be from an interface.
            Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
    
            // Adapt to TransactionAspectSupport's invokeWithinTransaction...
            return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
        }

    ransactionAspectSupport

    TransactionAspectSupport的最重要方法是invokeWithinTransaction方法,以下代码块是源码中截取的,已经省略了有回调功能的CallbackPreferringPlatformTransactionManager实现逻辑,这里只阐述非回调的事务管理。

    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;
            }
             //省略下面CallbackPreferringPlatformTransactionManager的实现逻辑
             //......
        }

    从invokeWithinTransaction方法的源码中,我们可以看到熟悉的影子。completeTransactionAfterThrowing方法对应于jdbc事务管理中的conn.rollBack()方法,而commitTransactionAfterReturning则对应conn.commitTX()方法,那么获取连接、开启事务在哪里呢?其实就在createTransactionIfNecessary方法里。

    我们还注意到invokeWithinTransaction方法里有个invocation.proceedWithInvocation()方法的调用,可以看看源码中的描述:

    // This is an around advice: Invoke the next interceptor in the chain.
    // This will normally result in a target object being invoked.

    可以知道这个方法的作用是调用拦截器链中的下一个拦截器(涉及到spring拦截器的知识不再在这里赘述),最终返回的是被@Transactional注解的方法的返回值。这个方法被try-catch包围了,其实这方法可以类比于jdbc事务管理中的执行的一系列CRUD方法。

  • 相关阅读:
    nodejs简易代理服务器
    request发送json-rpc请求
    nodejs使用sequelize操作mysql实例
    nodejs添加jsonwebtoken验证
    .net core下使用DbProviderFactories.GetFactory("")无法创建工厂的解决方案
    .net core 后台如何生成html字符串到前台_后台html字符串在前台显示编码状态
    .net core入门-跨域访问配置
    .net core入门-项目启动时报错:HTTP Error 502.5
    .net core项目启动时报_未处理Socket异常(以一种访问权限不允许的方式做了一个访问套接字的尝试。)
    winform批量更新数据_长时间的执行会导致界面卡死
  • 原文地址:https://www.cnblogs.com/zyh-s/p/13253574.html
Copyright © 2011-2022 走看看