开启事务标识
本小节的整体思路:1.注册一个advisor。2.每一个业务bean(比如UserService)初始化时都会调用后处理器,得到该bean的注解。然后将advisor逻辑应用进来。
在XML中配置tx:annotation-driven/ 。表示事务的开关。若没有配置,则spring中不存在事务的功能。
所以我们根据这个自定义配置,找到源码。
#TxNamespaceHandler public void init() { registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser()); registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser()); registerBeanDefinitionParser("jta-transaction-manager", new JtaTransactionManagerBeanDefinitionParser()); }复制代码
可以看到annotation-driven标签的解析是用AnnotationDrivenBeanDefinitionParser类表示的。我们进入其parse方法。
public BeanDefinition parse(Element element, ParserContext parserContext) { registerTransactionalEventListenerFactory(parserContext); String mode = element.getAttribute("mode"); if ("aspectj".equals(mode)) { // mode="aspectj" registerTransactionAspect(element, parserContext); } else { // mode="proxy" AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext); } return null; }复制代码
如果annotation-driven标签配置mode="aspectj",则用registerTransactionAspect方法来解析。默认走下面
private static class AopAutoProxyConfigurer { public static void configureAutoProxyCreator(Element element, ParserContext parserContext) { AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element); String txAdvisorBeanName = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME; if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) { Object eleSource = parserContext.extractSource(element); //1. 创建TransactionAttributeSource的bean RootBeanDefinition sourceDef = new RootBeanDefinition( "org.springframework.transaction.annotation.AnnotationTransactionAttributeSource"); sourceDef.setSource(eleSource); sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); //注册bean。beanname用规则自动生成 String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef); //2. 创建TransactionInterceptor的bean RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class); interceptorDef.setSource(eleSource); interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); registerTransactionManager(element, interceptorDef); interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName)); String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef); //3. 创建BeanFactoryTransactionAttributeSourceAdvisor的bean RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class); advisorDef.setSource(eleSource); advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); // BeanFactoryTransactionAttributeSourceAdvisor //包含AnnotationTransactionAttributeSource和TransactionInterceptor advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName)); advisorDef.getPropertyValues().add("adviceBeanName", interceptorName); if (element.hasAttribute("order")) { advisorDef.getPropertyValues().add("order", element.getAttribute("order")); } parserContext.getRegistry().registerBeanDefinition(txAdvisorBeanName, advisorDef); CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource); compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName)); compositeDef.addNestedComponent(new BeanComponentDefinition(interceptorDef, interceptorName)); compositeDef.addNestedComponent(new BeanComponentDefinition(advisorDef, txAdvisorBeanName)); parserContext.registerComponent(compositeDef); } }}public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) { return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source); }复制代码
注册InfrastructureAdvisorAutoProxyCreator的目的是什么呢?
从上面的继承关系能看出:当所有bean实例化的时候会调用
#AbstractAutoProxyCreator public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean != null) { //构建key Object cacheKey = getCacheKey(bean.getClass(), beanName); //对bean进行封装 if (!this.earlyProxyReferences.contains(cacheKey)) { return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { if (beanName != null && this.targetSourcedBeans.contains(beanName)) { return bean; } if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { return bean; } if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } // 找出增强器 Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); //根据上面的增强器创建代理 Object proxy = createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; }//找出增强器,并判断增强器是否满足要求protected Object[] getAdvicesAndAdvisorsForBean(Class beanClass, String beanName, TargetSource targetSource) { Listadvisors = findEligibleAdvisors(beanClass, beanName); if (advisors.isEmpty()) { return DO_NOT_PROXY; } return advisors.toArray(); }protected List findEligibleAdvisors(Class beanClass, String beanName) { //找增强器 List candidateAdvisors = findCandidateAdvisors(); //看增强器是否与对应class匹配或者class内部方法匹配也行。 List eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); extendAdvisors(eligibleAdvisors); if (!eligibleAdvisors.isEmpty()) { eligibleAdvisors = sortAdvisors(eligibleAdvisors); } return eligibleAdvisors; }protected List findCandidateAdvisors() { return this.advisorRetrievalHelper.findAdvisorBeans(); }public List findAdvisorBeans() { String[] advisorNames = null; synchronized (this) { advisorNames = this.cachedAdvisorBeanNames; if (advisorNames == null) {//根据类类型获取所有Advisor类 //此时就会获取到上面注册的BeanFactoryTransactionAttributeSourceAdvisor。因为它是一个advisor advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this.beanFactory, Advisor.class, true, false); this.cachedAdvisorBeanNames = advisorNames; } } if (advisorNames.length == 0) { return new LinkedList (); } List advisors = new LinkedList (); for (String name : advisorNames) { if (isEligibleBean(name)) { if (this.beanFactory.isCurrentlyInCreation(name)) { if (logger.isDebugEnabled()) { logger.debug("Skipping currently created advisor '" + name + "'"); } } else { try { advisors.add(this.beanFactory.getBean(name, Advisor.class)); } catch (BeanCreationException ex) { } throw ex; } } } } return advisors; }protected List findAdvisorsThatCanApply( List candidateAdvisors, Class beanClass, String beanName) { ProxyCreationContext.setCurrentProxiedBeanName(beanName); try { return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass); } finally { ProxyCreationContext.setCurrentProxiedBeanName(null); } } public static List findAdvisorsThatCanApply(List candidateAdvisors, Class clazz) { if (candidateAdvisors.isEmpty()) { return candidateAdvisors; } List eligibleAdvisors = new LinkedList (); for (Advisor candidate : candidateAdvisors) { if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) { eligibleAdvisors.add(candidate); } } boolean hasIntroductions = !eligibleAdvisors.isEmpty(); for (Advisor candidate : candidateAdvisors) { if (candidate instanceof IntroductionAdvisor) { // IntroductionAdvisor这种增强已经处理 continue; }//对普通bean的处理 if (canApply(candidate, clazz, hasIntroductions)) { eligibleAdvisors.add(candidate); } } return eligibleAdvisors; } public static boolean canApply(Advisor advisor, Class targetClass, boolean hasIntroductions) { if (advisor instanceof IntroductionAdvisor) { return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass); } else if (advisor instanceof PointcutAdvisor) { PointcutAdvisor pca = (PointcutAdvisor) advisor;//是这个类型 //走到这里 return canApply(pca.getPointcut(), targetClass, hasIntroductions); } else { // It doesn't have a pointcut so we assume it applies. return true; } }复制代码
当前我们判断UserService是否适用于此增强方法。当前的advisor就是BeanFactoryTransactionAttributeSourceAdvisor实例。pca.getPointcut()返回TransactionAttributeSourcePointcut实例。
public static boolean canApply(Pointcut pc, Class targetClass, boolean hasIntroductions) { if (!pc.getClassFilter().matches(targetClass)) { return false; } MethodMatcher methodMatcher = pc.getMethodMatcher();//返回自身this if (methodMatcher == MethodMatcher.TRUE) { return true; } IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null; if (methodMatcher instanceof IntroductionAwareMethodMatcher) { introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher; } Set> classes = new LinkedHashSet >(ClassUtils.getAllInterfacesForClassAsSet(targetClass)); classes.add(targetClass); for (Class clazz : classes) { Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz); for (Method method : methods) { if ((introductionAwareMethodMatcher != null && introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) || methodMatcher.matches(method, targetClass)) { return true; } } } return false; }#TransactionAttributeSourcePointcut public boolean matches(Method method, Class targetClass) { if (TransactionalProxy.class.isAssignableFrom(targetClass)) { return false; } TransactionAttributeSource tas = getTransactionAttributeSource(); return (tas == null || tas.getTransactionAttribute(method, targetClass) != null); } //提取事务标签protected TransactionAttribute computeTransactionAttribute(Method method, Class targetClass) { if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) { return null; } Class userClass = ClassUtils.getUserClass(targetClass); //代表接口中方法 //specificMethod代表实现类方法 Method specificMethod = ClassUtils.getMostSpecificMethod(method, userClass); // specificMethod = BridgeMethodResolver.findBridgedMethod(specificMethod); // 查看方法中是否存在事务申明 TransactionAttribute txAttr = findTransactionAttribute(specificMethod); if (txAttr != null) { return txAttr; } // 查看方法所在类中是否存在事务申明 txAttr = findTransactionAttribute(specificMethod.getDeclaringClass()); if (txAttr != null && ClassUtils.isUserLevelMethod(method)) { return txAttr; } //到接口中找 if (specificMethod != method) { // 查找接口方法 txAttr = findTransactionAttribute(method); if (txAttr != null) { return txAttr; } // 到接口中的类去找 txAttr = findTransactionAttribute(method.getDeclaringClass()); if (txAttr != null && ClassUtils.isUserLevelMethod(method)) { return txAttr; } } return null; }#SpringTransactionAnnotationParserpublic TransactionAttribute parseTransactionAnnotation(AnnotatedElement ae) { AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(ae, Transactional.class); if (attributes != null) { return parseTransactionAnnotation(attributes); } else { return null; } }protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) { RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute(); Propagation propagation = attributes.getEnum("propagation"); rbta.setPropagationBehavior(propagation.value()); Isolation isolation = attributes.getEnum("isolation"); rbta.setIsolationLevel(isolation.value()); rbta.setTimeout(attributes.getNumber("timeout").intValue()); rbta.setReadOnly(attributes.getBoolean("readOnly")); rbta.setQualifier(attributes.getString("value")); ArrayList rollBackRules = new ArrayList (); Class [] rbf = attributes.getClassArray("rollbackFor"); for (Class rbRule : rbf) { RollbackRuleAttribute rule = new RollbackRuleAttribute(rbRule); rollBackRules.add(rule); } String[] rbfc = attributes.getStringArray("rollbackForClassName"); for (String rbRule : rbfc) { RollbackRuleAttribute rule = new RollbackRuleAttribute(rbRule); rollBackRules.add(rule); } Class [] nrbf = attributes.getClassArray("noRollbackFor"); for (Class rbRule : nrbf) { NoRollbackRuleAttribute rule = new NoRollbackRuleAttribute(rbRule); rollBackRules.add(rule); } String[] nrbfc = attributes.getStringArray("noRollbackForClassName"); for (String rbRule : nrbfc) { NoRollbackRuleAttribute rule = new NoRollbackRuleAttribute(rbRule); rollBackRules.add(rule); } rbta.getRollbackRules().addAll(rollBackRules); return rbta; }复制代码
终于,我们看到了获取注解标记的代码。首先会判断是否有Transactianal注解。 事务增强器
TransactionInterceptor 支持整个事务架构。那么它是如何实现事务特性的呢。
public Object invoke(final MethodInvocation invocation) throws Throwable { Class targetClass = invocation.getThis() != null?AopUtils.getTargetClass(invocation.getThis()):null; return this.invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() { public Object proceedWithInvocation() throws Throwable { return invocation.proceed(); } }); }protected Object invokeWithinTransaction(Method method, Class targetClass, final TransactionAspectSupport.InvocationCallback invocation) throws Throwable {//获取对应事务属性 final TransactionAttribute txAttr = this.getTransactionAttributeSource().getTransactionAttribute(method, targetClass); //获取TransactionManager final PlatformTransactionManager tm = this.determineTransactionManager(txAttr); //构建一个方法的ID。(类.方法 如 service.UserServiceImpl.save) final String joinpointIdentification = this.methodIdentification(method, targetClass); // if(txAttr != null && tm instanceof CallbackPreferringPlatformTransactionManager) { try {//编程式事务处理 Object result = ((CallbackPreferringPlatformTransactionManager)tm).execute(txAttr, new TransactionCallback
-
创建事务 protected TransactionInfo createTransactionIfNecessary( PlatformTransactionManager tm, TransactionAttribute txAttr, final String joinpointIdentification) { if(txAttr != null && ((TransactionAttribute)txAttr).getName() == null) { //封装一下txAttr,目的提供更多功能 txAttr = new DelegatingTransactionAttribute((TransactionAttribute)txAttr) { public String getName() { return joinpointIdentification; } }; } TransactionStatus status = null; if(txAttr != null) { if(tm != null) {//获取事务 status = tm.getTransaction((TransactionDefinition)txAttr); } else if(this.logger.isDebugEnabled()) { } } //根据指定的属性与status准备一个TransactionInfo return this.prepareTransactionInfo(tm, txAttr, joinpointIdentification, status); } //事务获取和信息的构建 public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException { Object transaction = this.doGetTransaction(); boolean debugEnabled = this.logger.isDebugEnabled(); if(definition == null) { definition = new DefaultTransactionDefinition(); } //判断当前线程是否存在事务。(依据是:当前线程记录的连接不为空且连接中的transactionActive不为空) if(this.isExistingTransaction(transaction)) { //当前线程存在事务 return this.handleExistingTransaction((TransactionDefinition)definition, transaction, debugEnabled); //事务超时设置验证 } else if(((TransactionDefinition)definition).getTimeout() < -1) { throw new InvalidTimeoutException("Invalid transaction timeout", ((TransactionDefinition)definition).getTimeout()); //当前线程不存在事务 } else if(((TransactionDefinition)definition).getPropagationBehavior() == 2) { throw new IllegalTransactionStateException("No existing transaction found for transaction marked with propagation 'mandatory'"); } else if(((TransactionDefinition)definition).getPropagationBehavior() != 0 && ((TransactionDefinition)definition).getPropagationBehavior() != 3 && ((TransactionDefinition)definition).getPropagationBehavior() != 6) { if(((TransactionDefinition)definition).getIsolationLevel() != -1 && this.logger.isWarnEnabled()) { this.logger.warn("Custom isolation level specified but no actual transaction initiated; isolation level will effectively be ignored: " + definition); }
boolean newSynchronization = this.getTransactionSynchronization() == 0; return this.prepareTransactionStatus((TransactionDefinition)definition, (Object)null, true, newSynchronization, debugEnabled, (Object)null); } else {//空挂起 AbstractPlatformTransactionManager.SuspendedResourcesHolder suspendedResources = this.suspend((Object)null); try { boolean newSynchronization = this.getTransactionSynchronization() != 2; //构建DefaultTransactionStatus DefaultTransactionStatus status = this.newTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, suspendedResources); //构造transaction,包括设置connectionHolder、隔离级别、timeout //如果是新连接,绑定到当前线程 this.doBegin(transaction, (TransactionDefinition)definition); //新同步事务的设置,针对当前线程的设置 this.prepareSynchronization(status, (TransactionDefinition)definition); return status; } catch (RuntimeException var7) { } catch (Error var8) { } } }复制代码
获取事务 protected Object doGetTransaction() { DataSourceTransactionManager.DataSourceTransactionObject txObject = new DataSourceTransactionManager.DataSourceTransactionObject(); //保存点设置。是否允许保存点取决于是否设置允许嵌入式事务 txObject.setSavepointAllowed(this.isNestedTransactionAllowed()); //若当前线程已经记录数据库连接则使用原有连接 ConnectionHolder conHolder = (ConnectionHolder)TransactionSynchronizationManager.getResource(this.dataSource); //false表示非新创建连接 txObject.setConnectionHolder(conHolder, false); return txObject; }
-
//构建事务protected void doBegin(Object transaction, TransactionDefinition definition) { DataSourceTransactionManager.DataSourceTransactionObject txObject = (DataSourceTransactionManager.DataSourceTransactionObject)transaction; Connection con = null; try { if(txObject.getConnectionHolder() == null || txObject.getConnectionHolder().isSynchronizedWithTransaction()) { Connection newCon = this.dataSource.getConnection(); txObject.setConnectionHolder(new ConnectionHolder(newCon), true); } txObject.getConnectionHolder().setSynchronizedWithTransaction(true); con = txObject.getConnectionHolder().getConnection(); //设置隔离级别 Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition); txObject.setPreviousIsolationLevel(previousIsolationLevel); //更改自动提交设置,由Spring控制提交 if(con.getAutoCommit()) { txObject.setMustRestoreAutoCommit(true); con.setAutoCommit(false); } //设置标志位。标示当前连接已经被事务激活 txObject.getConnectionHolder().setTransactionActive(true); int timeout = this.determineTimeout(definition); if(timeout != -1) { txObject.getConnectionHolder().setTimeoutInSeconds(timeout); } if(txObject.isNewConnectionHolder()) { //将当前获取到的连接绑定到当前线程 TransactionSynchronizationManager.bindResource(this.getDataSource(), txObject.getConnectionHolder()); } } catch (Throwable var7) { if(txObject.isNewConnectionHolder()) { DataSourceUtils.releaseConnection(con, this.dataSource); txObject.setConnectionHolder((ConnectionHolder)null, false); } throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", var7); } }复制代码
-
-
处理已经存在的事务 上面是普通事务建立的过程,但Spring中支持多种事务传播规则,这些是在已经存在的事务的基础上进行进一步的处理。
private TransactionStatus handleExistingTransaction(TransactionDefinition definition, Object transaction, boolean debugEnabled) throws TransactionException { if(definition.getPropagationBehavior() == 5) { throw new IllegalTransactionStateException("Existing transaction found for transaction marked with propagation 'never'"); } else { AbstractPlatformTransactionManager.SuspendedResourcesHolder suspendedResources; boolean newSynchronization; if(definition.getPropagationBehavior() == 4) { if(debugEnabled) { this.logger.debug("Suspending current transaction"); }
suspendedResources = this.suspend(transaction); newSynchronization = this.getTransactionSynchronization() == 0; return this.prepareTransactionStatus(definition, (Object)null, false, newSynchronization, debugEnabled, suspendedResources); } else if(definition.getPropagationBehavior() == 3) { if(debugEnabled) { this.logger.debug("Suspending current transaction, creating new transaction with name [" + definition.getName() + "]"); } // 新事务的建立 suspendedResources = this.suspend(transaction); try { newSynchronization = this.getTransactionSynchronization() != 2; DefaultTransactionStatus status = this.newTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, suspendedResources); this.doBegin(transaction, definition); this.prepareSynchronization(status, definition); return status; } catch (RuntimeException var7) { this.resumeAfterBeginException(transaction, suspendedResources, var7); throw var7; } catch (Error var8) { this.resumeAfterBeginException(transaction, suspendedResources, var8); throw var8; } } else { boolean newSynchronization; //嵌入式事务的处理 if(definition.getPropagationBehavior() == 6) { if(!this.isNestedTransactionAllowed()) { throw new NestedTransactionNotSupportedException("Transaction manager does not allow nested transactions by default - specify 'nestedTransactionAllowed' property with value 'true'"); } else { if(debugEnabled) { this.logger.debug("Creating nested transaction with name [" + definition.getName() + "]"); } if(this.useSavepointForNestedTransaction()) { //如果没有可以使用保存点的方式控制事务回滚,那么在嵌入事务的建立初始建立保存点 DefaultTransactionStatus status = this.prepareTransactionStatus(definition, transaction, false, false, debugEnabled, (Object)null); status.createAndHoldSavepoint(); return status; } else { newSynchronization = this.getTransactionSynchronization() != 2; DefaultTransactionStatus status = this.newTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, (Object)null); this.doBegin(transaction, definition); this.prepareSynchronization(status, definition); return status; } } } else { if(debugEnabled) { this.logger.debug("Participating in existing transaction"); } if(this.isValidateExistingTransaction()) { if(definition.getIsolationLevel() != -1) { Integer currentIsolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel(); if(currentIsolationLevel == null || currentIsolationLevel.intValue() != definition.getIsolationLevel()) { Constants isoConstants = DefaultTransactionDefinition.constants; throw new IllegalTransactionStateException("Participating transaction with definition [" + definition + "] specifies isolation level which is incompatible with existing transaction: " + (currentIsolationLevel != null?isoConstants.toCode(currentIsolationLevel, "ISOLATION_"):"(unknown)")); } } if(!definition.isReadOnly() && TransactionSynchronizationManager.isCurrentTransactionReadOnly()) { throw new IllegalTransactionStateException("Participating transaction with definition [" + definition + "] is not marked as read-only but existing transaction is"); } } newSynchronization = this.getTransactionSynchronization() != 2; return this.prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, (Object)null); } } } }复制代码
当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的事务中运行。在TransactionDefinition定义中包括了如下几个表示传播行为的常量。
1。TransactionDefinition.PROPAGATION_REQUIRES_NEW: 创建一个新的事务,如果当前存在事务,则把当前事务挂起
2。TransactionDefinition.PROPAGATION_NESTED: 如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行
- 准备事务信息 当已经建立事务连接并完成了事务信息的提取后,会将所有事务信息统一记录在TransactionInfo类型的实例中。它包含目标开始前的所有状态信息,一旦事务执行失败,Spring会通过TransactionInfo类型的实例信息来进行回滚等后续工作。