spring声明式事务源码剖析(中)

来源:互联网 发布:ssh建立连接的端口号 编辑:程序博客网 时间:2024/06/06 01:01

TransactionInterceptor这个类我们在上一篇中已经认识了,这一篇我们来看一下,它是如何完成事务的拦截。spring代码版本v.4.2.4.RELEASE.

  1. TransactionInterceptor.invoke

    @Overridepublic 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();        }    });}
  2. 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);        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<Object>() {                            @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();            }        }    }

    这个方法开启事务,执行业务方法,关闭事务,返回业务执行结果;

  3. TransactionAspectSupport.createTransactionIfNecessary

    这个方法开启事务,事务的开启最终转嫁给 PlatformTransactionManager。对于一般的开发我们都应用单个关系型数据库,所以对应的PlatformTransactionManger为 DataSourceTransactionManager

  4. DataSourceTransactionManager.getTransaction

    该方法其父类中实现

  5. AbstractPlatformTransactionManager.getTransaction

    /** * This implementation handles propagation behavior. Delegates to * {@code doGetTransaction}, {@code isExistingTransaction} * and {@code doBegin}. * @see #doGetTransaction * @see #isExistingTransaction * @see #doBegin */@Overridepublic final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {    Object transaction = doGetTransaction();// Cache debug flag to avoid repeated checks.boolean debugEnabled = logger.isDebugEnabled();if (definition == null) {    // Use defaults if no transaction definition given.    definition = new DefaultTransactionDefinition(); //事务不存在时}if (isExistingTransaction(transaction)) { //事务已存在    // Existing transaction found -> check propagation behavior to find out how to behave.    return handleExistingTransaction(definition, transaction, debugEnabled);}// Check definition settings for new transaction.if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {    throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout());}// No existing transaction found -> check propagation behavior to find out how to proceed.//事务传播判断if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {    throw new IllegalTransactionStateException(            "No existing transaction found for transaction marked with propagation 'mandatory'");}else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||        definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||        definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {    SuspendedResourcesHolder suspendedResources = suspend(null);    if (debugEnabled) {        logger.debug("Creating new transaction with name [" + definition.getName() + "]: " + definition);    }    try {        boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);        DefaultTransactionStatus status = newTransactionStatus(                definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);        doBegin(transaction, definition);  //开启事务        prepareSynchronization(status, definition);//同步事务        return status;    }    catch (RuntimeException ex) {        resume(null, suspendedResources);        throw ex;    }    catch (Error err) {        resume(null, suspendedResources);        throw err;    }}else {    // Create "empty" transaction: no actual transaction, but potentially synchronization.    if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {        logger.warn("Custom isolation level specified but no actual transaction initiated; " +                "isolation level will effectively be ignored: " + definition);    }    boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);    return prepareTransactionStatus(definition, null, true, newSynchronization, debugEnabled, null);}

    }

方法定义如上.在学习spring事务时,需要注意如下几个类或接口

TransactionDefinition:事务接口TransactionAttribute    事务接口扩展TransactionStatus   事务状态PlatformTransactionManager 统一事务管理平台

对于如上的spring事务传播机制进行总结如下(我相信很多人都看过这个表格)

事务传播类型 行为 PROPAGATION_SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行 PROPAGATION_MANDATORY 使用当前的事务,如果没有事务,则抛出异常 PROPAGATION_NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起;注意区分PROPAGATION_REQUIRES_NEW PROPAGATION_NEVER 以非事务方式执行,如果当前存在事务,则抛出异常 PROPAGATION_REQUIRED 如果当前没有事务,则新建一个事务;如果已经存在一个事务中,则加入到这个事务中 PROPAGATION_REQUIRES_NEW 如果当前存在事务,把当前事务挂起,并新建事务,在支持savepoint的platform可以进行事务部分回滚;注意区分PROPAGATION_NOT_SUPPORTED PROPATATION_NESTED 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROGATION_REQUIRED类似的操作
  1. AbstractPlatformTransactionManager.doBegin(Object transaction, TransactionDefinition definition)

    它的实现在子类DataSourceTransactionManager

  2. DataSourceTransactionManager.doBegin

    这个方法获取Connection 并打开事务,它依赖于关系数据库的事务支持程度,所以说spring不重新发明轮子。

关于应用xml配置的声明式事务,已经至此完毕,对于应用注解式的事务管理,我们下篇再剖析。

原创粉丝点击