spring事务的入口
   
    TxAdviceBeanDefinitionParser解释
    
     <tx:advice/>
    
    这里将解析tx的配置
    
    
     @Override protected Class<?> getBeanClass(Element element) { return TransactionInterceptor.class; }
    
    ,生成TransactionInterceptor对象,
    
     public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable
    
    继承TransactionAspectSupport ,其中有个方法invokeWithinTransaction()特别重要:
   
 //protected修饰,不允许其他包和无关类调用
    protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation) throws Throwable {
        // 获取对应事务属性.如果事务属性为空(则目标方法不存在事务)
        final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
     // 根据事务的属性获取beanFactory中的PlatformTransactionManager(spring事务管理器的顶级接口),一般这里或者的是DataSourceTransactiuonManager
        final PlatformTransactionManager tm = determineTransactionManager(txAttr);
     // 目标方法唯一标识(类.方法,如service.UserServiceImpl.save)
        final String joinpointIdentification = methodIdentification(method, targetClass);
     //如果txAttr为空或者tm 属于非CallbackPreferringPlatformTransactionManager,执行目标增强     ①
        if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
            //看是否有必要创建一个事务,根据事务传播行为,做出相应的判断
            TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
            Object retVal = null;
            try {
          //回调方法执行,执行目标方法(原有的业务逻辑)
                retVal = invocation.proceedWithInvocation();
            }
            catch (Throwable ex) {
                // 异常回滚
                completeTransactionAfterThrowing(txInfo, ex);
                throw ex;
            }
            finally {
          //清除信息
                cleanupTransactionInfo(txInfo);
            }
        //提交事务
            commitTransactionAfterReturning(txInfo);
            return retVal;
        }
     //编程式事务处理(CallbackPreferringPlatformTransactionManager) 不做重点分析
        else {
            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();
            }
        }
    }
    
    
    spring事务架构
   
    事务的定义,在这里就不再累赘啦。但是在此之前,必须要知道的是spring事务的架构定义。
    
    spring事物管理高层抽象主要包括3个接口:PlatformTransactionManager(事务管理器)、TransactionDefinition(事物定义信息)、TransactionStatus(事物具体运行状态)。
   
    1、
    
     PlatformTransactionManager
    
    
    
    
    重点说说DataSourceTransactionManager,是否大家还记得这个类,在以前没继承springboot快速开发的时候,这个就是我们配置的事务管理器。
    
    首先这个类继承了抽象类AbstractPlatformTransactionManager
    
    
    
    这个类中,比较重要的是:
    
    (1)getTransaction()获取事务,在源码中是这样解释:
    
    根据,返回当前活动的事务或创建一个新的事务指定的传播行为。注意,隔离级别或超时等参数只会被应用用于新事务,因此在参与活动事务时将被忽略。此外,不是所有的事务定义设置将被支持,每个事务管理器:一个正确的事务管理器实现.当遇到不支持的设置时,应该抛出异常。
    
    上面规则的一个例外是只读标志,它应该是只读的.如果不支持显式只读模式,则忽略。本质上讲,
    
    只读标志只是潜在优化的一个提示。
   
    (2)commit(TransactionStatus status)方法,事务提交(回滚、提交)
    
    
    
    其中遇到做多的坑,
    
     基本就是这个Transaction rolled back because it has been marked as rollback-only
    
   
if (status.isNewTransaction() || isFailEarlyOnGlobalRollbackOnly()) {
				throw new UnexpectedRollbackException(
						"Transaction rolled back because it has been marked as rollback-only");
			}
    这个在方法命名时,需要注意
    
     方法命名规范
    
    (例如:查询就使用get,query等),以及在查询操作和更改操作的时候,抛异常时,需要特别注意
    
     事务的传播级别
    
    。
    
    在方法processCommit(defStatus);中有一个特别重要的代码
   
finally {
			cleanupAfterCompletion(status);
		}
    主要的作用是
    
     无论成功与否都释放当前事务
    
    ,以下是DataSourceTransactionManager的实现
   
@Override
	protected void doCleanupAfterCompletion(Object transaction) {
		DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
		// Remove the connection holder from the thread, if exposed.
		if (txObject.isNewConnectionHolder()) {
			TransactionSynchronizationManager.unbindResource(this.dataSource);
		}
		// Reset connection.
		Connection con = txObject.getConnectionHolder().getConnection();
		try {
			if (txObject.isMustRestoreAutoCommit()) {
				con.setAutoCommit(true);
			}
			DataSourceUtils.resetConnectionAfterTransaction(con, txObject.getPreviousIsolationLevel());
		}
		catch (Throwable ex) {
			logger.debug("Could not reset JDBC Connection after transaction", ex);
		}
		if (txObject.isNewConnectionHolder()) {
			if (logger.isDebugEnabled()) {
				logger.debug("Releasing JDBC Connection [" + con + "] after transaction");
			}
			DataSourceUtils.releaseConnection(con, this.dataSource);
		}
		txObject.getConnectionHolder().clear();
	}
    2.
    
     Transactiondefinition事务传播行为
    
    
    spring在TransactionDefinition接口中规定了7种类型的事务传播行为,它们规定了事务方法和事务方法发生嵌套调用时事务如何进行传播:
    
    事务传播行为类型 事务传播行为类型 说明 PROPAGATION_REQUIRED 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
   
    PROPAGATION_SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行。
    
    PROPAGATION_MANDATORY 使用当前的事务,如果当前没有事务,就抛出异常。
    
    PROPAGATION_REQUIRES_NEW 新建事务,如果当前存在事务,把当前事务挂起。
    
    PROPAGATION_NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
   
PROPAGATION_NEVER 以非事务方式执行,如果当前存在事务,则抛出异常。
    PROPAGATION_NESTED
    
    如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。
    
    3.
    
     TransactionStatus
    
    
    
    
    
     Spring Boot全局事务配置(二)
    
   
    
    
    总结
   
至此整个spring的事务过程也就结束了,全局事务的配置请参考第二篇.
 
