protected virtual SuspendedResourcesHolder Suspend(object transaction) { if (TransactionSynchronizationManager.IsSynchronizationActive()) { var suspendedSynchronizations = DoSuspendSynchronization(); try { object suspendedResources = null; if (transaction != null) { suspendedResources = DoSuspend(transaction); } var name = TransactionSynchronizationManager.GetCurrentTransactionName(); TransactionSynchronizationManager.SetCurrentTransactionName(null); var readOnly = TransactionSynchronizationManager.IsCurrentTransactionReadOnly(); TransactionSynchronizationManager.SetCurrentTransactionReadOnly(false); var isolationLevel = TransactionSynchronizationManager.GetCurrentTransactionIsolationLevel(); TransactionSynchronizationManager.SetCurrentTransactionIsolationLevel(null); var wasActive = TransactionSynchronizationManager.IsActualTransactionActive(); TransactionSynchronizationManager.SetActualTransactionActive(false); return(new SuspendedResourcesHolder(suspendedResources, suspendedSynchronizations, name, readOnly, isolationLevel, wasActive)); } catch (Exception) { // doSuspend failed - original transaction is still active... DoResumeSynchronization(suspendedSynchronizations); throw; } } else if (transaction != null) { // Transaction active but no synchronization active. var suspendedResources = DoSuspend(transaction); return(new SuspendedResourcesHolder(suspendedResources)); } else { // Neither transaction nor synchronization active. return(null); } }
private ITransactionStatus HandleExistingTransaction(ITransactionDefinition definition, object transaction) { if (definition.PropagationBehavior == AbstractTransactionDefinition.PROPAGATION_NEVER) { throw new IllegalTransactionStateException( "Existing transaction found for transaction marked with propagation 'never'"); } if (definition.PropagationBehavior == AbstractTransactionDefinition.PROPAGATION_NOT_SUPPORTED) { _logger?.LogDebug("Suspending current transaction"); var suspendedResources = Suspend(transaction); return(PrepareTransactionStatus(definition, null, false, TransactionSynchronization == SYNCHRONIZATION_ALWAYS, suspendedResources)); } if (definition.PropagationBehavior == AbstractTransactionDefinition.PROPAGATION_REQUIRES_NEW) { _logger?.LogDebug("Suspending current transaction, creating new transaction with name [{name}]", definition.Name); var suspendedResources = Suspend(transaction); try { var status = NewTransactionStatus(definition, transaction, true, TransactionSynchronization != SYNCHRONIZATION_NEVER, suspendedResources); DoBegin(transaction, definition); PrepareSynchronization(status, definition); return(status); } catch (Exception ex) { ResumeAfterBeginException(transaction, suspendedResources, ex); throw; } } if (definition.PropagationBehavior == AbstractTransactionDefinition.PROPAGATION_NESTED) { if (!NestedTransactionAllowed) { throw new NestedTransactionNotSupportedException( "Transaction manager does not allow nested transactions by default - " + "specify 'nestedTransactionAllowed' property with value 'true'"); } _logger?.LogDebug("Creating nested transaction with name [{name}]", definition.Name); 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. var status = PrepareTransactionStatus(definition, transaction, false, false, 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 // in case of a pre-existing JTA transaction. var status = NewTransactionStatus(definition, transaction, true, TransactionSynchronization != SYNCHRONIZATION_NEVER, null); DoBegin(transaction, definition); PrepareSynchronization(status, definition); return(status); } } // Assumably PROPAGATION_SUPPORTS or PROPAGATION_REQUIRED. _logger?.LogDebug("Participating in existing transaction"); if (ValidateExistingTransaction) { if (definition.IsolationLevel != AbstractTransactionDefinition.ISOLATION_DEFAULT) { var currentIsolationLevel = TransactionSynchronizationManager.GetCurrentTransactionIsolationLevel(); if (currentIsolationLevel == null || currentIsolationLevel != definition.IsolationLevel) { throw new IllegalTransactionStateException("Participating transaction with definition [" + definition + "] specifies isolation level which is incompatible with existing transaction: "); } } if (!definition.IsReadOnly && TransactionSynchronizationManager.IsCurrentTransactionReadOnly()) { throw new IllegalTransactionStateException("Participating transaction with definition [" + definition + "] is not marked as read-only but existing transaction is"); } } var newSynchronization = TransactionSynchronization != SYNCHRONIZATION_NEVER; return(PrepareTransactionStatus(definition, transaction, false, newSynchronization, null)); }