3、Spring建立事務

接上節事務執行流程,這是第3點的解析。
建立事務主要兩部分:ide

  1. 獲取事務狀態
  2. 構建事務信息

獲取事務狀態
代碼以下:線程

@Override
    public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
    //1.獲取事務
    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();
    }

    //判斷當前線程是否存在事務,判斷依據爲當前線程記錄鏈接不爲空且鏈接中的(connectionHolder)中的transactionActive屬性不爲空
    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.
    //若是當前線程不存在事務,可是@Transactional卻聲明事務爲PROPAGATION_MANDATORY拋出異常
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
        throw new IllegalTransactionStateException(
                "No existing transaction found for transaction marked with propagation 'mandatory'");
    }
    //若是當前線程不存在事務,PROPAGATION_REQUIRED、PROPAGATION_REQUIRES_NEW、PROPAGATION_NESTED都得建立事務
    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 {
            //默認返回true
            boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
            //構建事務狀態
            DefaultTransactionStatus status = newTransactionStatus(
                    definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
            //構造transaction、包括設置connectionHolder、隔離級別、timeout
            //若是是新事務,綁定到當前線程
            doBegin(transaction, definition);
            //新事務同步設置,針對當前線程
            prepareSynchronization(status, definition);
            return status;
        }
        catch (RuntimeException ex) {
            resume(null, suspendedResources);
            throw ex;
        }
        catch (Error err) {
            resume(null, suspendedResources);
            throw err;
        }
    }
    else {
        // Create "empty" transaction: no actual transaction, but potentially synchronization.
        if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
            logger.warn("Custom isolation level specified but no actual transaction initiated; " +
                    "isolation level will effectively be ignored: " + definition);
        }
        //聲明事務是PROPAGATION_SUPPORTS
        boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
        return prepareTransactionStatus(definition, null, true, newSynchronization, debugEnabled, null);
    }
}

構建事務信息debug

  1. 獲取事務,建立對應的事務實例,這裏使用的是DataSourceTransactionManager中的doGetTransaction方法,建立基於JDBC的事務實例,若是當前線程中存在關於dataSoruce的鏈接,那麼直接使用。這裏有一個對保存點的設置,是否開啓容許保存點取決因而否設置了容許嵌入式事務。DataSourceTransactionManager默認是開啓的。
  2. 若是當先線程存在事務,則轉向嵌套的事務處理。是否存在事務在DataSourceTransactionManager的isExistingTransaction方法中
  3. 事務超時設置驗證
  4. 事務PropagationBehavior屬性的設置驗證
  5. 構建DefaultTransactionStatus。
  6. 完善transaction,包括設置connectionHolder、隔離級別、timeout,若是是新事務,綁定到當前線程
  7. 將事務信息記錄在當前線程中
相關文章
相關標籤/搜索