spring事務管理源碼解析之事務開啓

說在前面java

本文轉自「天河聊技術」微信公衆號spring

@Transactional實現數據庫

 

正文微信

源碼解析app

先看下這個註解內容ide

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {

這個註解能夠用在方法上、類上、接口上ui

@AliasFor("transactionManager")
String value() default "";

這個屬性是能夠指定事務管理器,若是不指定默認是beanName=transactionManager的這個this

Propagation propagation() default Propagation.REQUIRED;

事務的傳播機制是默認有事務線程

Isolation isolation() default Isolation.DEFAULT;

事務的隔離級別是數據庫默認的debug

int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;

事務的超時時間也是數據庫默認的

boolean readOnly() default false;

默認事務是非只讀的

Class<? extends Throwable>[] rollbackFor() default {};

默認不指定遇到哪些異常進行事務回滾,可是運行時異常都會進行事務回滾

String[] rollbackForClassName() default {};

遇到異常進行事務回滾的異常類型

Class<? extends Throwable>[] noRollbackFor() default {};

遇到異常不進行事務回滾的異常類型

String[] noRollbackForClassName() default {};

遇到事務不進行異常回滾的異常類名

 

進入事務攔截器的org.springframework.transaction.interceptor.TransactionInterceptor#invoke方法

@Override
@Nullable
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, invocation::proceed);
}

進入這個方法

org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction

@Nullable
   protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
         final InvocationCallback invocation) throws Throwable {

      // If the transaction attribute is null, the method is non-transactional.若是事務屬性爲空,則該方法是非事務的。
      TransactionAttributeSource tas = getTransactionAttributeSource();
//    獲取事務屬性
      final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
      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 {
         final ThrowableHolder throwableHolder = new ThrowableHolder();

         // It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
         try {
            Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr, 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.
                     throwableHolder.throwable = ex;
                     return null;
                  }
               }
               finally {
                  cleanupTransactionInfo(txInfo);
               }
            });

            // Check result state: It might indicate a Throwable to rethrow.
            if (throwableHolder.throwable != null) {
               throw throwableHolder.throwable;
            }
            return result;
         }
         catch (ThrowableHolderException ex) {
            throw ex.getCause();
         }
         catch (TransactionSystemException ex2) {
            if (throwableHolder.throwable != null) {
               logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
               ex2.initApplicationException(throwableHolder.throwable);
            }
            throw ex2;
         }
         catch (Throwable ex2) {
            if (throwableHolder.throwable != null) {
               logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
            }
            throw ex2;
         }
      }
   }
//     獲取事務屬性
      final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);

進入這個方法

org.springframework.transaction.interceptor.AbstractFallbackTransactionAttributeSource#getTransactionAttribute

@Override
@Nullable
public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
   if (method.getDeclaringClass() == Object.class) {
      return null;
   }

   // First, see if we have a cached value.
   Object cacheKey = getCacheKey(method, targetClass);
   Object cached = this.attributeCache.get(cacheKey);
   if (cached != null) {
      // Value will either be canonical value indicating there is no transaction attribute,值能夠是規範值,表示沒有事務屬性,
      // or an actual transaction attribute.或實際的事務屬性。
      if (cached == NULL_TRANSACTION_ATTRIBUTE) {
         return null;
      }
      else {
         return (TransactionAttribute) cached;
      }
   }
   else {
      // We need to work it out.咱們須要解決這個問題。
      TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
      // Put it in the cache.
      if (txAttr == null) {
         this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);
      }
      else {
         String methodIdentification = ClassUtils.getQualifiedMethodName(method, targetClass);
         if (txAttr instanceof DefaultTransactionAttribute) {
            ((DefaultTransactionAttribute) txAttr).setDescriptor(methodIdentification);
         }
         if (logger.isDebugEnabled()) {
            logger.debug("Adding transactional method '" + methodIdentification + "' with attribute: " + txAttr);
         }
         this.attributeCache.put(cacheKey, txAttr);
      }
      return txAttr;
   }
}
TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);

進入到這個方法

org.springframework.transaction.interceptor.AbstractFallbackTransactionAttributeSource#computeTransactionAttribute

@Nullable
protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
   // Don't allow no-public methods as required.不要容許非公開的方法。非public的方法沒有事務
   if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
      return null;
   }

   // Ignore CGLIB subclasses - introspect the actual user class.忽略CGLIB子類——內省實際的user類。
   Class<?> userClass = (targetClass != null ? ClassUtils.getUserClass(targetClass) : null);
   // The method may be on an interface, but we need attributes from the target class.方法可能在接口上,可是咱們須要目標類的屬性。
   // If the target class is null, the method will be unchanged.若是目標類爲空,則該方法將保持不變。
   Method specificMethod = ClassUtils.getMostSpecificMethod(method, userClass);
   // If we are dealing with method with generic parameters, find the original method.若是咱們處理具備泛型參數的方法,請找到原始方法。
   specificMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);

   // First try is the method in the target class.第一個try是目標類中的方法。
   TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
   if (txAttr != null) {
      return txAttr;
   }

   // Second try is the transaction attribute on the target class.第二個嘗試是目標類上的事務屬性。
   txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
   if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
      return txAttr;
   }

   if (specificMethod != method) {
      // Fallback is to look at the original method.退一步看原始方法。
      txAttr = findTransactionAttribute(method);
      if (txAttr != null) {
         return txAttr;
      }
      // Last fallback is the class of the original method.最後一個回退是原始方法的類。
      txAttr = findTransactionAttribute(method.getDeclaringClass());
      if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
         return txAttr;
      }
   }

   return null;
}

查找方法所在的類以及子類的同樣的方法

Method specificMethod = ClassUtils.getMostSpecificMethod(method, userClass);
public static Method getMostSpecificMethod(Method method, @Nullable Class<?> targetClass) {
      if (isOverridable(method, targetClass) &&
            targetClass != null && targetClass != method.getDeclaringClass()) {
         try {
            if (Modifier.isPublic(method.getModifiers())) {
               try {
                  return targetClass.getMethod(method.getName(), method.getParameterTypes());
               }
               catch (NoSuchMethodException ex) {
                  return method;
               }
            }
            else {
//             查詢method對象
               Method specificMethod =
                     ReflectionUtils.findMethod(targetClass, method.getName(), method.getParameterTypes());
               return (specificMethod != null ? specificMethod : method);
            }
         }
         catch (SecurityException ex) {
            // Security settings are disallowing reflective access; fall back to 'method' below.
         }
      }
      return method;
   }

若是處理的是具備泛型參數的方法找到原始的方法

specificMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);

根據方法查找事務屬性

TransactionAttribute txAttr = findTransactionAttribute(specificMethod);

進入到這個方法

org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#determineTransactionAttribute

@Nullable
   protected TransactionAttribute determineTransactionAttribute(AnnotatedElement ae) {
      for (TransactionAnnotationParser annotationParser : this.annotationParsers) {
//       調用事務註解解析器去解析方法的事務屬性
         TransactionAttribute attr = annotationParser.parseTransactionAnnotation(ae);
         if (attr != null) {
            return attr;
         }
      }
      return null;
   }

進入到這個方法

org.springframework.transaction.annotation.SpringTransactionAnnotationParser#parseTransactionAnnotation(java.lang.reflect.AnnotatedElement)

@Override
   @Nullable
   public TransactionAttribute parseTransactionAnnotation(AnnotatedElement ae) {
//    解析@Transactional註解的屬性
      AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
            ae, Transactional.class, false, false);
      if (attributes != null) {
//       解析事務註解
         return parseTransactionAnnotation(attributes);
      }
      else {
         return null;
      }
   }

進入到這個方法

org.springframework.transaction.annotation.SpringTransactionAnnotationParser#parseTransactionAnnotation(org.springframework.core.annotation.AnnotationAttributes)

//  解析@Transactional註解屬性
   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<RollbackRuleAttribute> 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;
   }

返回到這個方法的這一行代碼

org.springframework.transaction.interceptor.AbstractFallbackTransactionAttributeSource#computeTransactionAttribute

 

查找類上的事務屬性

txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());

返回到這個方法

org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction

//     解析事務管理器
      final PlatformTransactionManager tm = determineTransactionManager(txAttr);

進入到這個方法

org.springframework.transaction.interceptor.TransactionAspectSupport#determineTransactionManager

@Nullable
   protected PlatformTransactionManager determineTransactionManager(@Nullable TransactionAttribute txAttr) {
      // Do not attempt to lookup tx manager if no tx attributes are set若是沒有設置tx屬性,不要嘗試查找tx管理器
      if (txAttr == null || this.beanFactory == null) {
         return getTransactionManager();
      }

      String qualifier = txAttr.getQualifier();
      if (StringUtils.hasText(qualifier)) {
//       從beanFactory中獲取事務註解指定的事務管理器
         return determineQualifiedTransactionManager(this.beanFactory, qualifier);
      }
      else if (StringUtils.hasText(this.transactionManagerBeanName)) {
         return determineQualifiedTransactionManager(this.beanFactory, this.transactionManagerBeanName);
      }
      else {
//       若是事務註解沒有指定事務管理器就獲取默認的事務管理器
         PlatformTransactionManager defaultTransactionManager = getTransactionManager();
         if (defaultTransactionManager == null) {
            defaultTransactionManager = this.transactionManagerCache.get(DEFAULT_TRANSACTION_MANAGER_KEY);
            if (defaultTransactionManager == null) {
               defaultTransactionManager = this.beanFactory.getBean(PlatformTransactionManager.class);
               this.transactionManagerCache.putIfAbsent(
                     DEFAULT_TRANSACTION_MANAGER_KEY, defaultTransactionManager);
            }
         }
         return defaultTransactionManager;
      }
   }

若是事務註解中沒有指定事務管理器就獲取默認的事務管理器

if (txAttr == null || this.beanFactory == null) {
   return getTransactionManager();
}
if (StringUtils.hasText(qualifier)) {
//       若是事務註解中配置了事務管理器的beanName就從beanFactory中獲取事務註解指定的事務管理器
         return determineQualifiedTransactionManager(this.beanFactory, qualifier);
      }
else {
//       若是事務註解沒有指定事務管理器就獲取默認的事務管理器
         PlatformTransactionManager defaultTransactionManager = getTransactionManager();
         if (defaultTransactionManager == null) {
            defaultTransactionManager = this.transactionManagerCache.get(DEFAULT_TRANSACTION_MANAGER_KEY);
            if (defaultTransactionManager == null) {
               defaultTransactionManager = this.beanFactory.getBean(PlatformTransactionManager.class);
               this.transactionManagerCache.putIfAbsent(
                     DEFAULT_TRANSACTION_MANAGER_KEY, defaultTransactionManager);
            }
         }
         return defaultTransactionManager;
      }

返回到這個方法這一行代碼

org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction

   識別事務方法
      final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);

返回到這個方法這行

org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction

//        建立事務
         TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);

進入到這個方法

org.springframework.transaction.interceptor.TransactionAspectSupport#createTransactionIfNecessary

protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm,
         @Nullable 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) {
//          獲取事務
            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);
   }

進入到這個方法

org.springframework.transaction.support.AbstractPlatformTransactionManager#getTransaction

@Override
   public final TransactionStatus getTransaction(@Nullable 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 | Error ex) {
            resume(null, suspendedResources);
            throw ex;
         }
      }
      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);
      }
   }
//     獲取事務
      Object transaction = doGetTransaction();

進入到這個方法

org.springframework.jdbc.datasource.DataSourceTransactionManager#doGetTransaction

@Override
   protected Object doGetTransaction() {
      DataSourceTransactionObject txObject = new DataSourceTransactionObject();
//    是否容許嵌套事務
      txObject.setSavepointAllowed(isNestedTransactionAllowed());
      ConnectionHolder conHolder =
            (ConnectionHolder) TransactionSynchronizationManager.getResource(obtainDataSource());
      txObject.setConnectionHolder(conHolder, false);
      return txObject;
   }

返回到這個方法org.springframework.transaction.support.AbstractPlatformTransactionManager#getTransaction這行

//     若是事務已存在
      if (isExistingTransaction(transaction)) {
         // Existing transaction found -> check propagation behavior to find out how to behave.
         return handleExistingTransaction(definition, transaction, debugEnabled);
      }

進入這個方法

org.springframework.transaction.support.AbstractPlatformTransactionManager#handleExistingTransaction

private TransactionStatus handleExistingTransaction(
         TransactionDefinition definition, Object transaction, boolean debugEnabled)
         throws TransactionException {

//    不支持當前事務,若是事務存在則拋出異常
      if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
         throw new IllegalTransactionStateException(
               "Existing transaction found for transaction marked with propagation 'never'");
      }

//    不支持當前事務,老是執行非事務性的
      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);
      }

//    若是事務的傳播行爲是開啓新事務
      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 | Error beginEx) {
            resumeAfterBeginException(transaction, suspendedResources, beginEx);
            throw beginEx;
         }
      }

//    若是事務的嵌套行爲是嵌套事務
      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() + "]");
         }
         if (useSavepointForNestedTransaction()) {
            // Create savepoint within existing Spring-managed transaction,在現有的spring管理事務中建立保存點,
            // through the SavepointManager API implemented by TransactionStatus.經過事務狀態實現的SavepointManager API。
            // Usually uses JDBC 3.0 savepoints. Never activates Spring synchronization.一般使用JDBC 3.0保存點。歷來沒有激活春天同步。
            DefaultTransactionStatus status =
                  prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);
            status.createAndHoldSavepoint();
            return status;
         }
         else {
            // Nested transaction through nested begin and commit/rollback calls.經過嵌套的開始和提交/回滾調用嵌套事務
            // Usually only for JTA: Spring synchronization might get activated here 一般只適用於JTA:這裏可能會激活Spring同步
            // in case of a pre-existing JTA transaction. 若是存在已存在的JTA事務。
            boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
            DefaultTransactionStatus status = newTransactionStatus(
                  definition, transaction, true, newSynchronization, debugEnabled, null);
            doBegin(transaction, definition);
            prepareSynchronization(status, definition);
            return status;
         }
      }

      // Assumably PROPAGATION_SUPPORTS or PROPAGATION_REQUIRED.多半PROPAGATION_SUPPORTS或PROPAGATION_REQUIRED。
      if (debugEnabled) {
         logger.debug("Participating in existing transaction");
      }
      if (isValidateExistingTransaction()) {
         if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
            Integer currentIsolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
            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);
   }

找到這行

//        暫停給定的事務
         Object suspendedResources = suspend(transaction);

進入這個方法暫停當前事務

org.springframework.transaction.support.AbstractPlatformTransactionManager#suspend

@Nullable
   protected final SuspendedResourcesHolder suspend(@Nullable 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);
//          獲取事務的readOnly屬性
            boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();
//          設置readOnly=false
            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 | Error ex) {
            // doSuspend failed - original transaction is still active...doSuspend失敗-原始事務仍然是活動的…
            doResumeSynchronization(suspendedSynchronizations);
            throw ex;
         }
      }
      else if (transaction != null) {
         // Transaction active but no synchronization active.事務活動,但沒有同步活動。
         Object suspendedResources = doSuspend(transaction);
         return new SuspendedResourcesHolder(suspendedResources);
      }
      else {
         // Neither transaction nor synchronization active.事務和同步都不活動。
         return null;
      }
   }
開啓事務
            doBegin(transaction, definition);
@Override
   protected void doBegin(Object transaction, TransactionDefinition definition) {
      DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
      Connection con = null;

      try {
         if (!txObject.hasConnectionHolder() ||
               txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
//          獲取數據庫鏈接
            Connection newCon = obtainDataSource().getConnection();
            if (logger.isDebugEnabled()) {
               logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");
            }
            txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
         }

         txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
         con = txObject.getConnectionHolder().getConnection();

//       返回數據庫設置的事務隔離級別
         Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
         txObject.setPreviousIsolationLevel(previousIsolationLevel);

         // Switch to manual commit if necessary. This is very expensive in some JDBC drivers,
         // so we don't want to do it unnecessarily (for example if we've explicitly
         // configured the connection pool to set it already).
         if (con.getAutoCommit()) {
            txObject.setMustRestoreAutoCommit(true);
            if (logger.isDebugEnabled()) {
               logger.debug("Switching JDBC Connection [" + con + "] to manual commit");
            }
//          設置不自動提交
            con.setAutoCommit(false);
         }

//       設置事務是不是隻讀
         prepareTransactionalConnection(con, definition);
         txObject.getConnectionHolder().setTransactionActive(true);

         int timeout = determineTimeout(definition);
         if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
//          設置事務定義中的事務超時時間
            txObject.getConnectionHolder().setTimeoutInSeconds(timeout);
         }

         // Bind the connection holder to the thread.
         if (txObject.isNewConnectionHolder()) {
            TransactionSynchronizationManager.bindResource(obtainDataSource(), txObject.getConnectionHolder());
         }
      }

      catch (Throwable ex) {
         if (txObject.isNewConnectionHolder()) {
            DataSourceUtils.releaseConnection(con, obtainDataSource());
            txObject.setConnectionHolder(null, false);
         }
         throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);
      }
   }
//        返回數據庫設置的事務隔離級別
         Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);

進入這個方法

org.springframework.jdbc.datasource.DataSourceUtils#prepareConnectionForTransaction

@Nullable
   public static Integer prepareConnectionForTransaction(Connection con, @Nullable TransactionDefinition definition)
         throws SQLException {

      Assert.notNull(con, "No Connection specified");

      // Set read-only flag.
      if (definition != null && definition.isReadOnly()) {
         try {
            if (logger.isDebugEnabled()) {
               logger.debug("Setting JDBC Connection [" + con + "] read-only");
            }
            con.setReadOnly(true);
         }
         catch (SQLException | RuntimeException ex) {
            Throwable exToCheck = ex;
            while (exToCheck != null) {
               if (exToCheck.getClass().getSimpleName().contains("Timeout")) {
                  // Assume it's a connection timeout that would otherwise get lost: e.g. from JDBC 4.0
                  throw ex;
               }
               exToCheck = exToCheck.getCause();
            }
            // "read-only not supported" SQLException -> ignore, it's just a hint anyway
            logger.debug("Could not set JDBC Connection read-only", ex);
         }
      }

      // Apply specific isolation level, if any.
      Integer previousIsolationLevel = null;
      if (definition != null && definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
         if (logger.isDebugEnabled()) {
            logger.debug("Changing isolation level of JDBC Connection [" + con + "] to " +
                  definition.getIsolationLevel());
         }
//       若是事務隔離級別設置的是默認ISOLATION_DEFAULT,從數據庫獲取事務隔離級別
         int currentIsolation = con.getTransactionIsolation();
         if (currentIsolation != definition.getIsolationLevel()) {
            previousIsolationLevel = currentIsolation;
//          若是事務定義中定義了事務隔離級別,以這個爲準
            con.setTransactionIsolation(definition.getIsolationLevel());
         }
      }

      return previousIsolationLevel;
   }

 

說到最後

本次解析僅表明我的看法,僅供參考,未完待續。

相關文章
相關標籤/搜索