protected void PrepareSynchronization(DefaultTransactionStatus status, ITransactionDefinition definition)
 {
     if (status.NewSynchronization)
     {
         TransactionSynchronizationManager.ActualTransactionActive = status.HasTransaction();
         TransactionSynchronizationManager.CurrentTransactionIsolationLevel = definition.TransactionIsolationLevel != System.Data.IsolationLevel.Unspecified ? definition.TransactionIsolationLevel : IsolationLevel.Unspecified;
         TransactionSynchronizationManager.CurrentTransactionReadOnly = definition.ReadOnly;
         TransactionSynchronizationManager.CurrentTransactionName = definition.Name;
         TransactionSynchronizationManager.InitSynchronization();
     }
 }
 private void ProcessRollback(DefaultTransactionStatus status)
 {
     try
     {
         try
         {
             TriggerBeforeCompletion(status);
             if (status.HasSavepoint)
             {
                 if (status.Debug)
                 {
                     log.Debug("Rolling back transaction to savepoint.");
                 }
                 status.RollbackToHeldSavepoint();
             }
             else if (status.IsNewTransaction)
             {
                 if (status.Debug)
                 {
                     log.Debug("Initiating transaction rollback");
                 }
                 DoRollback(status);
             }
             else if (status.HasTransaction())
             {
                 if (status.LocalRollbackOnly)
                 {
                     if (status.Debug)
                     {
                         log.Debug("Participating transaction failed - marking existing transaction as rollback-only");
                     }
                 }
                 DoSetRollbackOnly(status);
             }
             else
             {
                 log.Debug("Should roll back transaction but cannot - no transaction available.");
             }
         }
         catch (Exception)
         {
             TriggerAfterCompletion(status, TransactionSynchronizationStatus.Unknown);
             throw;
         }
         TriggerAfterCompletion(status, TransactionSynchronizationStatus.Rolledback);
     }
     finally
     {
         CleanupAfterCompletion(status);
     }
 }
 /// <summary>
 /// Trigger afterCompletion callback, handling exceptions properly.
 /// </summary>
 /// <param name="status">object representing the transaction</param>
 /// <param name="completionStatus">
 /// Completion status according to <see cref="Spring.Transaction.Support.TransactionSynchronizationStatus"/>
 /// </param>
 private void TriggerAfterCompletion(DefaultTransactionStatus status, TransactionSynchronizationStatus completionStatus)
 {
     if (status.NewSynchronization)
     {
         IList synchronizations = TransactionSynchronizationManager.Synchronizations;
         if (!status.HasTransaction() || status.IsNewTransaction)
         {
             if (status.Debug)
             {
                 log.Debug("Triggering afterCompletion synchronization");
             }
             InvokeAfterCompletion(synchronizations, completionStatus);
         }
         else
         {
             //TODO investigate parallel of JTA/System.Txs
             log.Info("Transaction controlled outside of spring tx manager.");
             RegisterAfterCompletionWithExistingTransaction(status.Transaction, synchronizations);
         }
     }
 }
 /// <summary>
 /// Invoke doRollback, handling rollback exceptions properly.
 /// </summary>
 /// <param name="status">object representing the transaction</param>
 /// <param name="exception">the thrown application exception or error</param>
 /// <exception cref="Spring.Transaction.TransactionException">
 /// in case of a rollback error
 /// </exception>
 private void DoRollbackOnCommitException(DefaultTransactionStatus status, Exception exception)
 {
     try
     {
         if (status.IsNewTransaction)
         {
             if (status.Debug)
             {
                 log.Debug("Initiating transaction rollback on commit exception.");
             }
             DoRollback(status);
         }
         else if (status.HasTransaction())
         {
             if (status.Debug)
             {
                 log.Debug("Marking existing transaction as rollback-only after commit exception", exception);
             }
             DoSetRollbackOnly(status);
         }
     }
     catch (Exception)
     {
         //TODO investigate rollback behavior...
         log.Error("Commit exception overridden by rollback exception", exception);
         TriggerAfterCompletion(status, TransactionSynchronizationStatus.Unknown);
         throw;
     }
     TriggerAfterCompletion(status, TransactionSynchronizationStatus.Rolledback);
 }
        /**
         * Trigger <code>afterCompletion</code> callbacks.
         * @param status object representing the transaction
         * @param completionStatus completion status according to TransactionSynchronization constants
         */
        private void TriggerAfterCompletion(DefaultTransactionStatus status, TransactionSynchronizationStatus completionStatus)
        {
            if (status.NewSynchronization)
            {
                var synchronizations = TransactionSynchronizationManager.Synchronizations.ToGenericList<ITransactionSynchronization>();
                if (synchronizations != null)
                {
                    if (!status.HasTransaction() || status.NewSynchronization)
                    {
                        if (status.Debug)
                        {
                            Logger.Trace("Triggering afterCompletion synchronization");
                        }

                        // No transaction or new transaction for the current scope ->
                        // invoke the afterCompletion callbacks immediately
                        this.InvokeAfterCompletion(synchronizations, completionStatus);
                    }
                    else if (!(synchronizations.Count < 1))
                    {
                        // 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.
                        this.RegisterAfterCompletionWithExistingTransaction(status.Transaction, synchronizations);
                    }
                }
            }
        }
        /**
         * Invoke <code>doRollback</code>, handling rollback exceptions properly.
         * @param status object representing the transaction
         * @param ex the thrown application exception or error
         * @throws TransactionException in case of rollback failure
         * @see #doRollback
         */
        private void DoRollbackOnCommitException(DefaultTransactionStatus status, Exception ex)
        {
            try
            {
                if (status.IsNewTransaction)
                {
                    if (status.Debug)
                    {
                        Logger.Debug("Initiating transaction rollback after commit exception", ex);
                    }

                    this.DoRollback(status);
                }
                else if (status.HasTransaction() && this.globalRollbackOnParticipationFailure)
                {
                    if (status.Debug)
                    {
                        Logger.Debug("Marking existing transaction as rollback-only after commit exception", ex);
                    }

                    this.DoSetRollbackOnly(status);
                }
            }
            catch (Exception rbex)
            {
                Logger.Error("Commit exception overridden by rollback exception", ex);
                this.TriggerAfterCompletion(status, TransactionSynchronizationStatus.Unknown);
                throw;
            }

            this.TriggerAfterCompletion(status, TransactionSynchronizationStatus.Rolledback);
        }
        /**
	 * Process an actual rollback.
	 * The completed flag has already been checked.
	 * @param status object representing the transaction
	 * @throws TransactionException in case of rollback failure
	 */
        private void ProcessRollback(DefaultTransactionStatus status)
        {
            try
            {
                try
                {
                    this.TriggerBeforeCompletion(status);
                    if (status.HasSavepoint)
                    {
                        if (status.Debug)
                        {
                            Logger.Debug("Rolling back transaction to savepoint");
                        }

                        status.RollbackToHeldSavepoint();
                    }
                    else if (status.IsNewTransaction)
                    {
                        if (status.Debug)
                        {
                            Logger.Debug("Initiating transaction rollback");
                        }

                        this.DoRollback(status);
                    }
                    else if (status.HasTransaction())
                    {
                        if (status.LocalRollbackOnly || this.globalRollbackOnParticipationFailure)
                        {
                            if (status.Debug)
                            {
                                Logger.Debug(
                                    "Participating transaction failed - marking existing transaction as rollback-only");
                            }

                            this.DoSetRollbackOnly(status);
                        }
                        else
                        {
                            if (status.Debug)
                            {
                                Logger.Debug(
                                    "Participating transaction failed - letting transaction originator decide on rollback");
                            }
                        }
                    }
                    else
                    {
                        Logger.Debug("Should roll back transaction but cannot - no transaction available");
                    }
                }
                catch (Exception ex)
                {
                    this.TriggerAfterCompletion(status, TransactionSynchronizationStatus.Unknown);
                    throw;
                }

                this.TriggerAfterCompletion(status, TransactionSynchronizationStatus.Rolledback);
            }
            finally
            {
                this.CleanupAfterCompletion(status);
            }
        }