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方法。

  • 相关阅读:
    SpringMVC防止重复提交
    Apache Lucene初探
    ORACLE触发器详解
    ORA-02287: sequence number not allowed here问题的解决
    数据库索引
    字符串 栈
    字符串 逆序
    汽水瓶
    查找 排序----有一只兔子,从出生后第3个月起每个月都生一只兔子,小兔子长到第三个月后每个月又生一只兔子,假如兔子都不死,问每个月的兔子总数为多少?
    usb串口的作用以及JLINK
  • 原文地址:https://www.cnblogs.com/zyh-s/p/13253574.html
Copyright © 2011-2022 走看看