Spring技术内幕——事务的创建,挂起,回归,提交(事务拦截器和抽象事务管理器)

来源:互联网 发布:数据恢复精灵免费吗 编辑:程序博客网 时间:2024/06/03 08:53

在涉及单个数据库局部事务的事务处理中,事务的最终实现和数据库的支持是紧密相关的。对局部数据库事务来说,一个事务处理的操作单元往往对应着一系列的数据库操作。

Spring事务处理主要分以下三个主要的过程:

(1)读取和处理在Spring IoC容器中配置的事务处理属性,并转化为Spring事务处理所需要的内部数据结构。这里涉及到的类是TransactionAttributeSourceAdvisor类。

(2)Spring的事务处理模块是通过AOP功能来实现声明式事务处理的,通用的事务处理过程包括:处理事务配置属性;事务配置属性与线程绑定等。

TransactionProxyFactoryBean是Spring中管理事务的IoC容器,通过它生成Proxy对象,通过TransactionInterceptor来完成堆代理方法的拦截,正式这些AOP的拦截功能,将事务处理的功能编织进来。

(3)底层事务处理实现。Spring中底层事务处理的实现交由PlatformTransactionManager的具体实现类来实现,如DataSourceTransactionManager和HibernateTransactionManager等。


TransactionProxyFactoryBean解析(这只是实现事务的一种方法,其他类也能实现事务,例如DataSourceTransactionManager!!!

public class TransactionProxyFactoryBean extends AbstractSingletonProxyFactoryBean          implements BeanFactoryAware {          private Pointcut pointcut;      //通过Spring IoC容器依赖注入的PlatformTransactionManager事务管理器      public void setTransactionManager(PlatformTransactionManager transactionManager) {      this.transactionInterceptor.setTransactionManager(transactionManager);      }      //通过依赖注入设置事务属性,以Properties形式存放的事务属性的key是方法名,      //value是事务属性描述,注入到TransactionInterceptor中      public void setTransactionAttributes(Properties transactionAttributes) {      this.transactionInterceptor.setTransactionAttributes(transactionAttributes);      }      //通过依赖注入设置事务属性源,通过事务属性源可以找到需要使用的事务属性      public void setTransactionAttributeSource(TransactionAttributeSource transactionAttributeSource) {      this.transactionInterceptor.setTransactionAttributeSource(transactionAttributeSource);      }      //通过依赖注入设置事务切入点,事务切入点根据触发条件调用事务拦截器      public void setPointcut(Pointcut pointcut) {          this.pointcut = pointcut;      }      //为事务拦截器设置管理事务的容器      public void setBeanFactory(BeanFactory beanFactory) {          this.transactionInterceptor.setBeanFactory(beanFactory);      }  //创建Spring AOP事务处理的通知器Advisor      protected Object createMainInterceptor() {          //调用事务拦截器的方法,检查必需的属性是否设置          this.transactionInterceptor.afterPropertiesSet();          //如果在Spring配置中设置了事务切入点          if (this.pointcut != null) {              //使用Spring默认的通知器封装事务切入点和事务拦截器              return new DefaultPointcutAdvisor(this.pointcut, this.transactionInterceptor);          }          //如果在Spring配置中没有设置事务切入点          else {              //使用TransactionAttributeSourceAdvisor封装默认的事务切入点              return new TransactionAttributeSourceAdvisor(this.transactionInterceptor);          }      }  }   
TransactionInterceptor的调用时机,完成了Bean的依赖注入后:



可以看到在AbstractSingletonProxyFactoryBean中的afterPropertiesSet方法中,调用了createMainInterceptor

//InitializingBean接口的实现方法,IoC容器初始化完成之后的回调方法  public void afterPropertiesSet() {          //事务的目标对象不能为空          if (this.target == null) {              throw new IllegalArgumentException("Property 'target' is required");          }          //事务目标对象必须是Bean引用,不能是Bean名称          if (this.target instanceof String) {              throw new IllegalArgumentException("'target' needs to be a bean reference, not a bean name as value");          }          //如果代理类加载器为null,则使用默认的类加载器作用代理类加载器          if (this.proxyClassLoader == null) {              this.proxyClassLoader = ClassUtils.getDefaultClassLoader();          }  //创建代理工厂,Spring事务管理容器TransactionProxyFactoryBean通过//ProxyFactory完成AOP的基本功能,ProxyFactory提供事务代理对象,并将事务拦//截器设置为事务目标对象方法的拦截器          ProxyFactory proxyFactory = new ProxyFactory();          //如果在事务拦截器之前配置了额外的拦截器          if (this.preInterceptors != null) {              //将这些事务之前的额外拦截器添加到通知器中              for (Object interceptor : this.preInterceptors) {      proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(interceptor));              }          }  //加入Spring AOP事务处理通知器,createMainInterceptor()方法  //由子类TransactionProxyFactoryBean提供实现    proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(createMainInterceptor()));          //如果在事务拦截器之后配置了额外拦截器          if (this.postInterceptors != null) {              //将这些事务之后的额外拦截器添加到通知器中              for (Object interceptor : this.postInterceptors) {      proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(interceptor));              }          }          //从当前容器中复制事务AOP相关配置到ProxyFactory中          proxyFactory.copyFrom(this);          //创建AOP的目标源          TargetSource targetSource = createTargetSource(this.target);          //为ProxyFactory设置AOP目标源          proxyFactory.setTargetSource(targetSource);          //如果事务配置使用了代理接口          if (this.proxyInterfaces != null) {              //为ProxyFactory设置代理接口              proxyFactory.setInterfaces(this.proxyInterfaces);          }          //如果事务代理不是直接应用于目标类或者接口          else if (!isProxyTargetClass()) {              //将目标源的所有接口都设置为ProxyFactory的接口              proxyFactory.setInterfaces(      ClassUtils.getAllInterfacesForClass(targetSource.getTargetClass(), this.proxyClassLoader));          }          //ProxyFactory对象根据给定的类加载器创建事务代理对象          //具体的创建过程我们在Spring的AOP源码分析中已经分析过,Spring根据是否          //实现接口而分别调用JDK动态代理或者CGLIB方式创建AOP代理对象          this.proxy = proxyFactory.getProxy(this.proxyClassLoader);      }  

事务拦截器TransactionInterceptor的实现


管理Spring事务的IoC容器TransactionProxyFactoryBean已经完成了事务配置的读取,设置好了事务拦截器和切入点。当应用调用被配置事务的方法时,首先通过getObject方法向Spring事务管理容器索取被被管理方法的事务属性,触发调用事务拦截器的拦截方法进行事务处理。

在对Spring AOP源码分析中关于AOP代理如何起作用时,我们知道Spring的AOP代理通过invoke回调方法对切入点方法进行拦截处理,这个invoke方法是AOP联盟的方法拦截器MethodInterceptor接口中定义的方法,用于对AOP代理对象的方法进行包装处理。事务拦截器TransactionInterceptor正是通过这个invoke拦截方法实现事务的拦截处理,源码如下:

//事务拦截器的拦截方法  public Object invoke(final MethodInvocation invocation) throws Throwable {          //通过AOP获取事务的目标类          Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);          //通过事务属性源TransactionAttributeSource读取事务的属性配置,即调用上面名称匹配  //事务属性源NameMatchTransactionAttributeSource的方法          final TransactionAttribute txAttr =      getTransactionAttributeSource().getTransactionAttribute(invocation.getMethod(), targetClass);  //获取Spring事务管理IoC容器配置的事务处理器          final PlatformTransactionManager tm = determineTransactionManager(txAttr);          //获取目标类指定方法的事务连接点          final String joinpointIdentification = methodIdentification(invocation.getMethod(), targetClass);  //区分不同类型的PlatformTransactionManager事务处理器,不同类型的事务处理器调用//方式不同。对CallbackPreferringPlatformTransactionManager,需要回调函数来//实现事务的创建和提交,对非CallbackPreferringPlatformTransactionManager来//说,则不需要使用回调函数来实现事务处理。          //非CallbackPreferringPlatformTransactionManager类型的事务处理器          if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {              //创建事务,将当前事务状态和信息保存到TransactionInfo对象中              TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);              Object retVal = null;              try {                  //沿着拦截器链调用处理,使得最后目标对象的方法得到调用                  retVal = invocation.proceed();              }              catch (Throwable ex) {                  //在调用拦截器拦过程中出现异常,则根据事务配置进行提交或回滚处理                  completeTransactionAfterThrowing(txInfo, ex);                  throw ex;              }              //清除与当前线程绑定的事务信息              finally {                  cleanupTransactionInfo(txInfo);              }              //通过事务处理器来对事务进行提交              commitTransactionAfterReturning(txInfo);              return retVal;          }          //CallbackPreferringPlatformTransactionManager类型的事务处理器          else {              //通过回调函数对事务进行处理              try {                  //执行实现TransactionCallback接口的doInTransaction回调方法                  Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr,                          new TransactionCallback<Object>() {                              //实现TransactionCallback接口匿名内部类的回调方法  public Object doInTransaction(TransactionStatus status) {      //创建和准备事务                                  TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);                                  try {                                      //沿着拦截器拦调用                                      return invocation.proceed();                                  }                                  //拦截器链处理过程中产生异常                                  catch (Throwable ex) {                                      //如果事务对异常进行回滚处理                                      if (txAttr.rollbackOn(ex)) {                                          //如果异常时运行时异常,则事务回滚处理                                         if (ex instanceof RuntimeException) {                                              throw (RuntimeException) ex;                                          }                                          //如果不是运行时异常,则提交处理                                          else {                                              throw new ThrowableHolderException(ex);                                          }                                      }                                      //如果事务对异常不进行回滚处理                                      else {                                          //提交处理                                          return new ThrowableHolder(ex);                                      }                                  }                                  //清除当前线程绑定的事务信息                                  finally {                                      cleanupTransactionInfo(txInfo);                                  }                              }                          });                  //对调用结果异常进行处理。  //如果是ThrowableHolder类型的异常,则转换为Throwable抛出                  if (result instanceof ThrowableHolder) {                      throw ((ThrowableHolder) result).getThrowable();                  }                  //如果不是ThrowableHolder类型的异常,则异常不做处理直接抛出                  else {                      return result;                  }              }              catch (ThrowableHolderException ex) {                  throw ex.getCause();              }          }      }  


事务创建(创建的结果是生成一个TransactionInfo对象)


事务拦截器TransactionInterceptor回调方法invoke通过调用TransactionAspectSupport事务切面支持类中的createTransactionIfNecessary和prepareTransactionInfo方法创建事务对象:

//根据给定的事务属性创建事务对象protected TransactionInfo createTransactionIfNecessary(PlatformTransactionManager tm, TransactionAttribute txAttr, final String joinpointIdentification) {//读取事务方法调用的事务配置属性if (txAttr != null && txAttr.getName() == null) {//如果事务名称为null,则使用方法的名称(事务连接点标识)作为事务名称,//调用一个实现DelegatingTransactionAttribute接口的匿名内部类txAttr = new DelegatingTransactionAttribute(txAttr) {//使用方法名称作为事务名称public String getName() {return joinpointIdentification;}};}//事务状态封装了事务执行的状态信息TransactionStatus status = null;if (txAttr != null) {if (tm != null) {//事务处理器创建事务,并且返回当前事务的状态信息status = tm.getTransaction(txAttr);}else {if (logger.isDebugEnabled()) {logger.debug("Skipping transactional joinpoint [" + joinpointIdentification +"] because no transaction manager has been configured");}}}//准备事务信息,事务信息TransactionInfo封装了事务配置和状态信息return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);} //准备事务信息protected TransactionInfo prepareTransactionInfo(PlatformTransactionManager tm,TransactionAttribute txAttr, String joinpointIdentification, TransactionStatus status) {//创建事务信息对象TransactionInfo txInfo = new TransactionInfo(tm, txAttr, joinpointIdentification);//如果事务属性不为null,需要为方法使用事务if (txAttr != null) {if (logger.isTraceEnabled()) {logger.trace("Getting transaction for [" + txInfo.getJoinpointIdentification() + "]");}//为事务信息对象设置事务状态txInfo.newTransactionStatus(status);}//如果事务属性为null,不需要为方法使用事务else {if (logger.isTraceEnabled())logger.trace("Don't need to create transaction for [" + joinpointIdentification +"]: This method isn't transactional.");}//把当前创建的事务信息对象和线程绑定txInfo.bindToThread();return txInfo;} 

通过上面对TransactionAspectSupport事务切面支持类创建事务信息对象的源码分析,我们了解了在创建事务信息对象过程中创建事务状态,将创建的事务信息对象和当前线程资源绑定等基本的处理流程。在创建事务信息对象的方法中,事务处理器的tm.getTransaction(txAttr);是真正底层创建事务对象的方法,下面我们继续分析事务处理器创建事务对象的过程。


抽象事务管理器AbstractPlatformTransactionManager获取事务:

抽象事务管理器AbstractPlatformTransactionManager提供了创建事务的模板,这个模板会被具体的事务处理器所使用,抽象事务管理器根据事务属性配置和当前线程绑定信息对事务是否需要创建以及如何创建进行一些通用的处理,然后把事务创建的底层细节交给具体的事务处理器实现。抽象事务管理器创建事务的模板方法如下:

public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {//doGetTransaction()方法是抽象方法,具体的实现由具体的事务处理器提供Object transaction = doGetTransaction();boolean debugEnabled = logger.isDebugEnabled();//如果没有配置事务属性,则使用默认的事务属性if (definition == null) {definition = new DefaultTransactionDefinition();}//检查当前线程是否存在事务,如果已存在事务,那么需要根据在事务属性中定义的事务传播属性来处理事务的产生if (isExistingTransaction(transaction)) {//处理已存在的事务的情况return handleExistingTransaction(definition, transaction, debugEnabled);}//检查事务属性中timeout超时属性设置是否合理if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout());}//对事务属性中配置的事务传播特性处理//如果事务传播特性配置的是mandatory,当前没有事务存在,抛出异常if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {throw new IllegalTransactionStateException("No existing transaction found for transaction marked with propagation 'mandatory'");}//如果事务传播特性为required、required_new或nestedelse 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 {//创建空事务,针对supported类型的事务传播特性,激活和当前线程绑定的事务boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);//准备事务状态return prepareTransactionStatus(definition, null, true, newSynchronization, debugEnabled, null);}}

//准备事务状态protected final DefaultTransactionStatus prepareTransactionStatus(TransactionDefinition definition, Object transaction, boolean newTransaction,boolean newSynchronization, boolean debug, Object suspendedResources) {//创建事务状态DefaultTransactionStatus status = newTransactionStatus(definition, transaction, newTransaction, newSynchronization, debug, suspendedResources);//准备事务状态prepareSynchronization(status, definition);return status;}//创建事务状态protected DefaultTransactionStatus newTransactionStatus(TransactionDefinition definition, Object transaction, boolean newTransaction,boolean newSynchronization, boolean debug, Object suspendedResources) {//判断是否是新事务,如果是新事务,则需要把事务属性存放到当前线程中boolean actualNewSynchronization = newSynchronization &&!TransactionSynchronizationManager.isSynchronizationActive();return new DefaultTransactionStatus(transaction, newTransaction, actualNewSynchronization,definition.isReadOnly(), debug, suspendedResources);}//初始化事务属性protected void prepareSynchronization(DefaultTransactionStatus status, TransactionDefinition definition) {if (status.isNewSynchronization()) {//设置当前是否有活跃事务TransactionSynchronizationManager.setActualTransactionActive(status.hasTransaction());//设置当前事务隔离级别TransactionSynchronizationManager.setCurrentTransactionIsolationLevel((definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) ?definition.getIsolationLevel() : null);TransactionSynchronizationManager.setCurrentTransactionReadOnly(definition.isReadOnly());//设置当前事务名称TransactionSynchronizationManager.setCurrentTransactionName(definition.getName());TransactionSynchronizationManager.initSynchronization();}}

抽象事务管理器AbstractPlatformTransactionManager处理已存在的事务:


对于新事务的处理相对比较简单,只需根据事务属性配置创建,同时将事务隔离级别等属性保存到事务绑定的线程资源中。而对于已存在的事务处理相对比较复杂一些,在抽象事务管理器AbstractPlatformTransactionManager中通过handleExistingTransaction方法来处理已存在的事务:

private TransactionStatus handleExistingTransaction(TransactionDefinition definition, Object transaction, boolean debugEnabled)throws TransactionException {//如果事务传播特性为:never,则抛出异常if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {throw new IllegalTransactionStateException("Existing transaction found for transaction marked with propagation 'never'");}//如果事务传播特性是not_supported,同时当前线程存在事务,则将事务挂起if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {if (debugEnabled) {logger.debug("Suspending current transaction");}//挂起事务Object suspendedResources = suspend(transaction);boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);//创建非事务的事务状态,让方法非事务地执行return prepareTransactionStatus(definition, null, false, newSynchronization, debugEnabled, suspendedResources);}//如果事务传播特性是required_new,则创建新事务,同时把当前线程中存在的//事务挂起if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {if (debugEnabled) {logger.debug("Suspending current transaction, creating new transaction with name [" +definition.getName() + "]");}//挂起已存在的事务SuspendedResourcesHolder suspendedResources = suspend(transaction);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 beginEx) {resumeAfterBeginException(transaction, suspendedResources, beginEx);throw beginEx;}catch (Error beginErr) {resumeAfterBeginException(transaction, suspendedResources, beginErr);throw beginErr;}}//如果事务传播特性是nested嵌套事务if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {//如果不允许事务嵌套,则抛出异常if (!isNestedTransactionAllowed()) {throw new NestedTransactionNotSupportedException("Transaction manager does not allow nested transactions by default - " +"specify 'nestedTransactionAllowed' property with value 'true'");}if (debugEnabled) {logger.debug("Creating nested transaction with name [" + definition.getName() + "]");}//如果允许使用savepoint保存点保存嵌套事务if (useSavepointForNestedTransaction()) {//为当前事务创建一个保存点DefaultTransactionStatus status =prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);status.createAndHoldSavepoint();return status;}//如果不允许使用savepoint保存点保存嵌套事务else {//使用JTA的嵌套commit/rollback调用boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);DefaultTransactionStatus status = newTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, null);doBegin(transaction, definition);prepareSynchronization(status, definition);return status;}}//对于事务传播特性为supported和required的处理if (debugEnabled) {logger.debug("Participating in existing transaction");}//校验已存在的事务,如果已有事务与事务属性配置不一致,则抛出异常if (isValidateExistingTransaction()) {//如果事务隔离级别不是默认隔离级别if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {//获取当前事务的隔离级别Integer currentIsolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();//如果获取到的当前事务隔离级别为null获取不等于事务属性配置的隔离级别if (currentIsolationLevel == null || currentIsolationLevel != 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, DefaultTransactionDefinition.PREFIX_ISOLATION) : "(unknown)"));}}//如果事务不是只读if (!definition.isReadOnly()) {//如果当前已有事务是只读if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {throw new IllegalTransactionStateException("Participating transaction with definition [" +definition + "] is not marked as read-only but existing transaction is");}}}boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);//返回当前事务的执行状态return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);}


事务的挂起:

如果当前线程存在事务,但事务传播特性又要求开启新事务时,需要将已有的事务进行挂起,事务的挂起涉及线程与事务信息的保存,实现源码如下:

protected final SuspendedResourcesHolder suspend(Object transaction) throws TransactionException {//如果事务是激活的,且当前线程事务同步机制也是激活状态if (TransactionSynchronizationManager.isSynchronizationActive()) {//挂起当前线程中所有同步的事务List<TransactionSynchronization> suspendedSynchronizations = doSuspendSynchronization();try {Object suspendedResources = null;//把挂起事务的操作交由具体的事务处理器处理if (transaction != null) {suspendedResources = doSuspend(transaction);}//在线程中保存与事务处理有关的信息,并将线程里有关的线程局部变量重置String name = TransactionSynchronizationManager.getCurrentTransactionName();//重置当前线程中事务相关的线程局部变量TransactionSynchronizationManager.setCurrentTransactionName(null);boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();TransactionSynchronizationManager.setCurrentTransactionReadOnly(false);Integer isolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(null);boolean wasActive = TransactionSynchronizationManager.isActualTransactionActive();TransactionSynchronizationManager.setActualTransactionActive(false);//将当前线程中事务相关信息保存return new SuspendedResourcesHolder(suspendedResources, suspendedSynchronizations, name, readOnly, isolationLevel, wasActive);}//对事务挂起操作中产生异常和错误的处理catch (RuntimeException ex) {doResumeSynchronization(suspendedSynchronizations);throw ex;}catch (Error err) {doResumeSynchronization(suspendedSynchronizations);throw err;}}//如果事务是激活的,但是事务同步机制不是激活的,则只需要保存事务状态,不//需要重置事务相关的线程局部变量else if (transaction != null) {Object suspendedResources = doSuspend(transaction);return new SuspendedResourcesHolder(suspendedResources);}//事务和事务同步机制都不是激活的,则不要想处理else {return null;}}

事务的挂起:

如果当前线程存在事务,但事务传播特性又要求开启新事务时,需要将已有的事务进行挂起,事务的挂起涉及线程与事务信息的保存,实现源码如下:

protected final SuspendedResourcesHolder suspend(Object transaction) throws TransactionException {//如果事务是激活的,且当前线程事务同步机制也是激活状态if (TransactionSynchronizationManager.isSynchronizationActive()) {//挂起当前线程中所有同步的事务List<TransactionSynchronization> suspendedSynchronizations = doSuspendSynchronization();try {Object suspendedResources = null;//把挂起事务的操作交由具体的事务处理器处理,如果具体的事务处理器不支持事务挂起,会抛异常if (transaction != null) {suspendedResources = doSuspend(transaction);}//在线程中保存与事务处理有关的信息,并将线程里有关的线程局部变量重置String name = TransactionSynchronizationManager.getCurrentTransactionName();//重置当前线程中事务相关的线程局部变量TransactionSynchronizationManager.setCurrentTransactionName(null);boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();TransactionSynchronizationManager.setCurrentTransactionReadOnly(false);Integer isolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(null);boolean wasActive = TransactionSynchronizationManager.isActualTransactionActive();TransactionSynchronizationManager.setActualTransactionActive(false);//将当前线程中事务相关信息保存return new SuspendedResourcesHolder(suspendedResources, suspendedSynchronizations, name, readOnly, isolationLevel, wasActive);}//对事务挂起操作中产生异常和错误的处理catch (RuntimeException ex) {doResumeSynchronization(suspendedSynchronizations);throw ex;}catch (Error err) {doResumeSynchronization(suspendedSynchronizations);throw err;}}//如果事务是激活的,但是事务同步机制不是激活的,则只需要保存事务状态,不//需要重置事务相关的线程局部变量else if (transaction != null) {Object suspendedResources = doSuspend(transaction);return new SuspendedResourcesHolder(suspendedResources);}//事务和事务同步机制都不是激活的,则不要想处理else {return null;}}

事务的提交:

当事务方法处理成功之后,需要将当前事务提交,将更改同步到数据库中,事务提交的入口调用在TransactionInterceptor的invoke方法事中时间,提交的实现源码如下:

public final void commit(TransactionStatus status) throws TransactionException {//如果事务的执行状态已经结束,则抛出异常if (status.isCompleted()) {throw new IllegalTransactionStateException("Transaction is already completed - do not call commit or rollback more than once per transaction");}DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;//如果事务执行状态时回滚if (defStatus.isLocalRollbackOnly()) {if (defStatus.isDebug()) {logger.debug("Transactional code has requested rollback");}//处理事务回滚processRollback(defStatus);return;}//如果事务没有被标记为回滚时提交,且事务状态时全局回滚if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {if (defStatus.isDebug()) {logger.debug("Global transaction is marked as rollback-only but transactional code requested commit");}//回滚处理processRollback(defStatus);//如果事务状态时新事务,或者在全局回滚时失败if (status.isNewTransaction() || isFailEarlyOnGlobalRollbackOnly()) {throw new UnexpectedRollbackException("Transaction rolled back because it has been marked as rollback-only");}return;}//处理提交processCommit(defStatus);}

//提交处理操作private void processCommit(DefaultTransactionStatus status) throws TransactionException {try {boolean beforeCompletionInvoked = false;try {//事务提交的准备工作,有具体的事务处理器完成prepareForCommit(status);triggerBeforeCommit(status);triggerBeforeCompletion(status);beforeCompletionInvoked = true;boolean globalRollbackOnly = false;//如果事务状态是新事务,或者全局回滚失败if (status.isNewTransaction() || isFailEarlyOnGlobalRollbackOnly()) {//设置事务全局回滚globalRollbackOnly = status.isGlobalRollbackOnly();}//嵌套事务处理if (status.hasSavepoint()) {if (status.isDebug()) {logger.debug("Releasing transaction savepoint");}//释放挂起事务保存点status.releaseHeldSavepoint();}//如果当前事务是新事务else if (status.isNewTransaction()) {if (status.isDebug()) {logger.debug("Initiating transaction commit");}//调用具体事务处理器提交事务doCommit(status);}//如果事务被标记为全局回滚if (globalRollbackOnly) {throw new UnexpectedRollbackException("Transaction silently rolled back because it has been marked as rollback-only");}}//提交过程中产生未预期的回滚异常,则回滚处理catch (UnexpectedRollbackException ex) {triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);throw ex;}//对提交过程中产生的事务异常处理catch (TransactionException ex) {//如果回滚失败,则进行回滚异常处理if (isRollbackOnCommitFailure()) {doRollbackOnCommitException(status, ex);}else {triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);}throw ex;}//对提交过程中产生的异常处理catch (RuntimeException ex) {//如果不是在完成前调用的if (!beforeCompletionInvoked) {//触发完成前的回调方法triggerBeforeCompletion(status);}//进行回滚异常处理doRollbackOnCommitException(status, ex);throw ex;}//对提交过程中产生的错误处理catch (Error err) {if (!beforeCompletionInvoked) {triggerBeforeCompletion(status);}doRollbackOnCommitException(status, err);throw err;}//触发提交之后的回调操作try {triggerAfterCommit(status);}finally {triggerAfterCompletion(status, TransactionSynchronization.STATUS_COMMITTED);}}//提交完成之后清除事务相关状态finally {cleanupAfterCompletion(status);}}


事务的回滚:

当在事务处理过程中产生异常,或者提交失败时,往往需要对数据库中已有的更改做回滚操作,即恢复到操作之前的状态,回滚的实现代码如下:

public final void rollback(TransactionStatus status) throws TransactionException {//如果事务状态已完成,则抛出异常if (status.isCompleted()) {throw new IllegalTransactionStateException("Transaction is already completed - do not call commit or rollback more than once per transaction");}DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;//处理回滚的操作processRollback(defStatus);} //回滚操作private void processRollback(DefaultTransactionStatus status) {try {try {//触发完成前的回调操作triggerBeforeCompletion(status);//嵌套事务回滚处理if (status.hasSavepoint()) {if (status.isDebug()) {logger.debug("Rolling back transaction to savepoint");}//回滚挂起在保存点的事务status.rollbackToHeldSavepoint();}//当前事务中创建新事务的回滚操作else if (status.isNewTransaction()) {if (status.isDebug()) {logger.debug("Initiating transaction rollback");}//回滚处理,由具体的事务处理器实现doRollback(status);}//如果在当前事务中没有新建事务else if (status.hasTransaction()) {//如果当前事务状态为本地回滚,或全局回滚失败if (status.isLocalRollbackOnly() || isGlobalRollbackOnParticipationFailure()) {if (status.isDebug()) {logger.debug("Participating transaction failed - marking existing transaction as rollback-only");}//设置当前事务状态为回滚doSetRollbackOnly(status);}//当前事务状态没有设置为本地回滚,且没有产生全局回滚失败,则//由线程中的前一个事务来处理回滚,这个步骤任何处理else {if (status.isDebug()) {logger.debug("Participating transaction failed - letting transaction originator decide on rollback");}}}//如果当前线程没有事务else {logger.debug("Should roll back transaction but cannot - no transaction available");}}//对回滚操作过程中的运行时异常和错误的处理catch (RuntimeException ex) {triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);throw ex;}catch (Error err) {triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);throw err;}//回滚操作完成后,触发回滚之后回调操作triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);}//清除回滚之后事务状态信息finally {cleanupAfterCompletion(status);}}

阅读全文
0 0