Spring事物傳播特性原始碼分析
阿新 • • 發佈:2018-12-22
PROPAGATION_REQUIRED:如果當前沒有事務,就新建一個事務,如果已經存在一個事務,就加入到這個事務中。這是最常見的選擇。
PROPAGATION_SUPPORTS:支援當前事務,如果當前沒有事務,就以非事務方式執行。
PROPAGATION_MANDATORY:使用當前的事務,如果當前沒有事務,就丟擲異常。
PROPAGATION_REQUIRES_NEW:新建事務,如果當前存在事務,把當前事務掛起。
PROPAGATION_NOT_SUPPORTED:以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。
PROPAGATION_NEVER:以非事務方式執行,如果當前存在事務,則丟擲異常。
PROPAGATION_NESTED:如果當前存在事務,則在巢狀事務內執行。如果當前沒有事務,則執行PROPAGATION_REQUIRED類似的操作。
public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException { //獲取事物物件(內建conection) Object transaction = doGetTransaction(); boolean debugEnabled = logger.isDebugEnabled(); if (definition == null) { definition = new DefaultTransactionDefinition(); } //這裡判斷是否已經存在一個事物,如果存在走其他邏輯 if (isExistingTransaction(transaction)) { return handleExistingTransaction(definition, transaction, debugEnabled); } if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) { throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout()); } //使用當前的事務,如果當前沒有事務,就丟擲異常 //程式碼走到這裡,說明isExistingTransaction返回false,當前上下文沒有事物。 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 { 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 { //PROPAGATION_SUPPORTS,支援當前事務,如果當前沒有事務,就以非事務方式執行。 //下面是如果當前沒有事物,就建立一個空事物。其實就是已非事物方式執行。 // 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); } }
上面程式碼主要是在當前上下文沒有事物的情況下的處理邏輯,
如果PROPAGATION_MANDATORY,則丟擲異常
如果PROPAGATION_REQUIRED,PROPAGATION_REQUIRES_NEW,PROPAGATION_NESTED,則建立一個新事物。
最後就是PROPAGATION_SUPPORTS,有就支援,沒有就已非事物執行。
/** * Create a TransactionStatus for an existing transaction. */ private TransactionStatus handleExistingTransaction( TransactionDefinition definition, Object transaction, boolean debugEnabled) throws TransactionException { //PROPAGATION_NEVER,如果是這個,那麼直接拋異常 //以非事務方式執行,如果當前存在事務,則丟擲異常。 if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) { throw new IllegalTransactionStateException( "Existing transaction found for transaction marked with propagation 'never'"); } //PROPAGATION_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); } //PROPAGATION_REQUIRES_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 | Error beginEx) { resumeAfterBeginException(transaction, suspendedResources, beginEx); throw beginEx; } } //如果當前存在事務,則在巢狀事務內執行。如果當前沒有事務,則執行PROPAGATION_REQUIRED類似的操作 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, // through the SavepointManager API implemented by TransactionStatus. // Usually uses JDBC 3.0 savepoints. Never activates Spring synchronization. DefaultTransactionStatus status = prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null); //所謂巢狀事物,其實就是JDBC的還原點,在當前位置建立還原點, status.createAndHoldSavepoint(); return status; } else { // Nested transaction through nested begin and commit/rollback calls. // Usually only for JTA: Spring synchronization might get activated here // in case of a pre-existing JTA transaction. 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. 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); }
上面程式碼大題邏輯就是如果已經存在一個事物,那麼如何處理的邏輯。