private void DoResumeSynchronization(List <ITransactionSynchronization> suspendedSynchronizations) { TransactionSynchronizationManager.InitSynchronization(); foreach (var synchronization in suspendedSynchronizations) { synchronization.Resume(); TransactionSynchronizationManager.RegisterSynchronization(synchronization); } }
public static void InvokeAfterCommit(List <ITransactionSynchronization> synchronizations) { if (synchronizations != null) { foreach (var synchronization in TransactionSynchronizationManager.GetSynchronizations()) { synchronization.AfterCommit(); } } }
protected virtual void PrepareSynchronization(DefaultTransactionStatus status, ITransactionDefinition definition) { if (status.IsNewSynchronization) { TransactionSynchronizationManager.SetActualTransactionActive(status.HasTransaction); TransactionSynchronizationManager.SetCurrentTransactionIsolationLevel(definition.IsolationLevel != AbstractTransactionDefinition.ISOLATION_DEFAULT ? definition.IsolationLevel : (int?)null); TransactionSynchronizationManager.SetCurrentTransactionReadOnly(definition.IsReadOnly); TransactionSynchronizationManager.SetCurrentTransactionName(definition.Name); TransactionSynchronizationManager.InitSynchronization(); } }
private List <ITransactionSynchronization> DoSuspendSynchronization() { var suspendedSynchronizations = TransactionSynchronizationManager.GetSynchronizations(); foreach (var synchronization in suspendedSynchronizations) { synchronization.Suspend(); } TransactionSynchronizationManager.ClearSynchronization(); return(suspendedSynchronizations); }
public static void TriggerBeforeCompletion(ILogger logger = null) { foreach (var synchronization in TransactionSynchronizationManager.GetSynchronizations()) { try { synchronization.BeforeCompletion(); } catch (Exception ex) { logger?.LogError(ex, "TransactionSynchronization.beforeCompletion threw exception"); } } }
public static void InvokeAfterCompletion(List <ITransactionSynchronization> synchronizations, int completionStatus, ILogger logger = null) { if (synchronizations != null) { foreach (var synchronization in TransactionSynchronizationManager.GetSynchronizations()) { try { synchronization.AfterCompletion(completionStatus); } catch (Exception ex) { logger.LogError("TransactionSynchronization.afterCompletion threw exception", ex); } } } }
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 void CleanupAfterCompletion(DefaultTransactionStatus status) { status.IsCompleted = true; if (status.IsNewSynchronization) { TransactionSynchronizationManager.Clear(); } if (status.IsNewTransaction) { DoCleanupAfterCompletion(status.Transaction); } if (status.SuspendedResources != null) { _logger?.LogDebug("Resuming suspended transaction after completion of inner transaction"); var transaction = status.HasTransaction ? status.Transaction : null; Resume(transaction, (SuspendedResourcesHolder)status.SuspendedResources); } }
protected virtual void Resume(object transaction, SuspendedResourcesHolder resourcesHolder) { if (resourcesHolder != null) { var suspendedResources = resourcesHolder.SuspendedResources; if (suspendedResources != null) { DoResume(transaction, suspendedResources); } var suspendedSynchronizations = resourcesHolder.SuspendedSynchronizations; if (suspendedSynchronizations != null) { TransactionSynchronizationManager.SetActualTransactionActive(resourcesHolder.WasActive); TransactionSynchronizationManager.SetCurrentTransactionIsolationLevel(resourcesHolder.IsolationLevel); TransactionSynchronizationManager.SetCurrentTransactionReadOnly(resourcesHolder.ReadOnly); TransactionSynchronizationManager.SetCurrentTransactionName(resourcesHolder.Name); DoResumeSynchronization(suspendedSynchronizations); } } }
private void TriggerAfterCompletion(DefaultTransactionStatus status, int completionStatus) { if (status.IsNewSynchronization) { var synchronizations = TransactionSynchronizationManager.GetSynchronizations(); TransactionSynchronizationManager.ClearSynchronization(); if (!status.HasTransaction || status.IsNewTransaction) { _logger?.LogTrace("Triggering afterCompletion synchronization"); // No transaction or new transaction for the current scope -> // invoke the afterCompletion callbacks immediately InvokeAfterCompletion(synchronizations, completionStatus); } else if (synchronizations.Count > 0) { // Existing transaction that we participate in, controlled outside // of the scope of this Spring transaction manager -> try to register // an afterCompletion callback with the existing (JTA) transaction. RegisterAfterCompletionWithExistingTransaction(status.Transaction, synchronizations); } } }
public static void TriggerAfterCompletion(int completionStatus) { var synchronizations = TransactionSynchronizationManager.GetSynchronizations(); InvokeAfterCompletion(synchronizations, completionStatus); }
public static void TriggerAfterCommit() { InvokeAfterCommit(TransactionSynchronizationManager.GetSynchronizations()); }
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)); }
protected virtual DefaultTransactionStatus NewTransactionStatus(ITransactionDefinition definition, object transaction, bool newTransaction, bool newSynchronization, object suspendedResources) { var actualNewSynchronization = newSynchronization && !TransactionSynchronizationManager.IsSynchronizationActive(); return(new DefaultTransactionStatus(transaction, newTransaction, actualNewSynchronization, definition.IsReadOnly, suspendedResources, _logger)); }