Spring事务源码解析

Ye6rupMjAWk.jpg

DataSourceTransactionManager 解析

  1. getTransaction(TransactionDefinition)
    主要目的开启一个事务,判断 是否 存在一个事务
    如果存在,则根据传播行为进行相应处理。===> 挂起当前事务 或者 是 抛异常
    如果不存在事务,也需要根据传播行为来。

流程:
1.获取 transaction object ,以判断是否存在当前事务
Object transaction = doGetTransaction() //模板方法,子类实现

获取的类型会根据实现的子类不同 类型会不同。

1.CglibAopProxy$DynamicAdvisedInterceptor.intercept 656
2.ReflectiveMethodInvocation.proceed() 179
3.TransactionInterceptor.invoke 96
4.TransactionAspectSupport.invokeWithinTransaction 277
5.TransactionAspectSupport.createTransactionIfNecessary 447
6.AbstractPlatformTransactionManager.getTransaction
7.DataSourceTransactionManager.doBegin

基于声明式事务管理的Aspect切面

  • TransactionAspectSupport 可以手动设置回滚 具体例子:http://www.cnblogs.com/liuzhenlei/p/6777644.html
    使用到了ThreadLocal

TransactionAttributerollbackOn

常见问题和解决方案: https://blog.csdn.net/bejustice/article/details/48245741?ref=myread

  • 注意:需要放在 public修饰的方法上,才会起作用。
  • 注解最好放在实现类上,为了基于类的代理。

TransactionAwareDataSourceProxy

  • 动态代理
  • 委派模式
    这个类继承了一个委派类,委派类是代理dataSource。
    这个类主要是在获取连接时,会通过动态代理,实际上去通过DataSourceUtils 去 getConnection ,这样连接就让Spring管理了。
    其底层应用就是使用ThreadLocal将当前连接绑定到当前线程。

解析tx xml parse 时 引入 的某些代码

package org.springframework.transaction.annotation;

类:SpringTransactionAnnotationParser

@Override
public TransactionAttribute parseTransactionAnnotation(AnnotatedElement ae) {
    //此行打一个断点
    AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(ae, Transactional.class);
    if (attributes != null) {
        return parseTransactionAnnotation(attributes);
    }
    else {
        return null;
    }
}

事务 rollback

  • 1.TransactionInterceptor 继承 抽象类 TransactionAspectSupport
    1. rollback的判断在TransactionAspectSupport的completeTransactionAfterThrowing方法中
    1. 具体的rollback会代理到DelegatingTransactionAttribute,传入的TransactionAttribute实现类是RuleBasedTransactionAttribute,这个类会判断有没用户自定义的rollback的异常,有就rollback,没有就roll 运行时异常.
      这个类继承DefaultTransactionAttribute
public boolean rollbackOn(Throwable ex) {
        if (logger.isTraceEnabled()) {
            logger.trace("Applying rules to determine whether transaction should rollback on " + ex);
        }

        RollbackRuleAttribute winner = null;
        int deepest = Integer.MAX_VALUE;

        if (this.rollbackRules != null) {
            for (RollbackRuleAttribute rule : this.rollbackRules) {
                int depth = rule.getDepth(ex);
                if (depth >= 0 && depth < deepest) {
                    deepest = depth;
                    winner = rule;
                }
            }
        }

        if (logger.isTraceEnabled()) {
            logger.trace("Winning rollback rule is: " + winner);
        }

        // User superclass behavior (rollback on unchecked) if no rule matches.
        if (winner == null) {
            logger.trace("No relevant rollback rule found: applying default rules");
            return super.rollbackOn(ex);
        }

        return !(winner instanceof NoRollbackRuleAttribute);
    }


Spring事务 0509

事务开启流程(以CGLIB为例):
1.执行通过 spring aop 代理后的类的某个被事务管理的方法

  1. CglibAopProxy.intercept() 开始执行。
    关键代码:
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();

3.ReflectiveMethodInvocation.proceed() 执行

return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
  1. TransactionInterceptor 的 invoke()方法
//继承关系,继承了 TransactionAspectSupport 
public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable 

@Override
public Object invoke(final 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, new InvocationCallback() {
        @Override
        public Object proceedWithInvocation() throws Throwable {
            return invocation.proceed();
        }
    });
}

5.TransactionAspectSupport.invokeWithinTransaction
关键代码

protected Object invokeWithinTransaction(Method method, Class targetClass, final InvocationCallback invocation)
            throws Throwable {

        // If the transaction attribute is null, the method is non-transactional.
        final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
        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 {
            // It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
            try {
                Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr,
                        new TransactionCallback() {
                            @Override
                            public Object doInTransaction(TransactionStatus 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.
                                        return new ThrowableHolder(ex);
                                    }
                                }
                                finally {
                                    cleanupTransactionInfo(txInfo);
                                }
                            }
                        });

                // Check result: It might indicate a Throwable to rethrow.
                if (result instanceof ThrowableHolder) {
                    throw ((ThrowableHolder) result).getThrowable();
                }
                else {
                    return result;
                }
            }
            catch (ThrowableHolderException ex) {
                throw ex.getCause();
            }
        }
}




6.TransactionAspectSupport.createTransactionIfNecessary

//这里 tm 传入的是 DataSourceTransactionManager
protected TransactionInfo createTransactionIfNecessary(
            PlatformTransactionManager tm, TransactionAttribute txAttr, final String joinpointIdentification) {

        // If no name specified, apply method identification as transaction name.
        if (txAttr != null && txAttr.getName() == null) {
            txAttr = new DelegatingTransactionAttribute(txAttr) {
                @Override
                public String getName() {
                    return joinpointIdentification;
                }
            };
        }

        TransactionStatus status = null;
        if (txAttr != null) {
            if (tm != null) {
                //关键代码,获取 transaction
                status = tm.getTransaction(txAttr);
            }
            else {
                if (logger.isDebugEnabled()) {
                    logger.debug("Skipping transactional joinpoint [" + joinpointIdentification +
                            "] because no transaction manager has been configured");
                }
            }
        }
        return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
}

7.AbstractPlatformTransactionManager.getTransaction

这样第一阶段,开启事务并获取连接已经完成


Rollback

rollback(TransactionStatus status) 
    -> processRollback()
           ->doRollback
                ->DataSourceTransactionManager.doRollback
                     ->con.rollback

其中rollback(TransactionStatus status)PlatformTransaction的接口方法
doRollbackAbstractPlatfromTransaction的抽象方法
最终的con.rollbackjdbc的接口方法

你可能感兴趣的:(Spring事务源码解析)