/// <summary>
 /// Notifies an enlisted object that a transaction is being prepared for commitment.
 /// </summary>
 /// <param name="preparingEnlistment">A <see cref="T:System.Transactions.PreparingEnlistment"/> object used to send a response to the transaction manager.</param>
 public void Prepare(PreparingEnlistment preparingEnlistment)
 {
     onTxComplete();
     try
     {
         using (var machineStoreForApplication = IsolatedStorageFile.GetMachineStoreForDomain())
         {
             var name = TransactionRecoveryInformationFileName;
             using (var file = machineStoreForApplication.CreateFile(name + ".temp"))
                 using (var writer = new BinaryWriter(file))
                 {
                     writer.Write(session.ResourceManagerId.ToString());
                     writer.Write(PromotableRavenClientEnlistment.GetLocalOrDistributedTransactionId(transaction).ToString());
                     writer.Write(session.DatabaseName ?? "");
                     writer.Write(preparingEnlistment.RecoveryInformation());
                     file.Flush(true);
                 }
             machineStoreForApplication.MoveFile(name + ".temp", name);
         }
     }
     catch (Exception e)
     {
         logger.ErrorException("Could not prepare distributed transaction", e);
         preparingEnlistment.ForceRollback(e);
         return;
     }
     preparingEnlistment.Prepared();
 }
Example #2
0
        static void HandleEndPrepare(IAsyncResult result)
        {
            PreparingEnlistment preparingEnlistment = (PreparingEnlistment)result.AsyncState;
            bool success = false;

            try
            {
                if (!result.CompletedSynchronously)
                {
                    PrepareAsyncResult.End(result);
                    preparingEnlistment.Prepared();
                }
                success = true;
            }
            //we need to swollow the TransactionException as it could because another party aborting it
            catch (TransactionException)
            {
            }
            finally
            {
                if (!success)
                {
                    preparingEnlistment.ForceRollback();
                }
            }
        }
Example #3
0
        void IEnlistmentNotification.Prepare(PreparingEnlistment preparingEnlistment)
        {
            bool success = false;

            try
            {
                IAsyncResult result = new PrepareAsyncResult(this, TransactionContext.handleEndPrepare, preparingEnlistment);
                if (result.CompletedSynchronously)
                {
                    PrepareAsyncResult.End(result);
                    preparingEnlistment.Prepared();
                }
                success = true;
            }
            //we need to swollow the TransactionException as it could because another party aborting it
            catch (TransactionException)
            {
            }
            finally
            {
                if (!success)
                {
                    preparingEnlistment.ForceRollback();
                }
            }
        }
            void IEnlistmentNotification.Prepare(PreparingEnlistment preparingEnlistment)
            {
                using (new SessionIdLoggingContext(sessionImplementor.SessionId))
                {
                    try
                    {
                        using (var tx = new TransactionScope(AmbientTransation))
                        {
                            if (sessionImplementor.ConnectionManager.IsConnected)
                            {
                                using (sessionImplementor.ConnectionManager.FlushingFromDtcTransaction)
                                {
                                    sessionImplementor.BeforeTransactionCompletion(null);
                                    foreach (var dependentSession in sessionImplementor.ConnectionManager.DependentSessions)
                                    {
                                        dependentSession.BeforeTransactionCompletion(null);
                                    }

                                    logger.Debug("prepared for DTC transaction");

                                    tx.Complete();
                                }
                            }
                        }
                        preparingEnlistment.Prepared();
                    }
                    catch (Exception exception)
                    {
                        logger.Error("DTC transaction prepare phase failed", exception);
                        preparingEnlistment.ForceRollback(exception);
                    }
                }
            }
        public void Prepare(PreparingEnlistment preparingEnlistment)
        {
            CheckDisposed();
            Log.Debug($"Two-phase transaction prepare (localid={_txId})", _connector.Id);

            // The PostgreSQL prepared transaction name is the distributed GUID + our connection's process ID, for uniqueness
            _preparedTxName = $"{_transaction.TransactionInformation.DistributedIdentifier}/{_connector.BackendProcessId}";

            try
            {
                using (_connector.StartUserAction())
                    _connector.ExecuteInternalCommand($"PREPARE TRANSACTION '{_preparedTxName}'");

                // The MSDTC, which manages escalated distributed transactions, performs the 2nd phase
                // asynchronously - this means that TransactionScope.Dispose() will return before all
                // resource managers have actually commit.
                // If the same connection tries to enlist to a new TransactionScope immediately after
                // disposing an old TransactionScope, its EnlistedTransaction must have been cleared
                // (or we'll throw a double enlistment exception). This must be done here at the 1st phase
                // (which is sync).
                if (_connector.Connection != null)
                {
                    _connector.Connection.EnlistedTransaction = null;
                }

                preparingEnlistment.Prepared();
            }
            catch (Exception e)
            {
                Dispose();
                preparingEnlistment.ForceRollback(e);
            }
        }
            void IEnlistmentNotification.Prepare(PreparingEnlistment preparingEnlistment)
            {
                using (new SessionIdLoggingContext(sessionImplementor.SessionId))
                {
                    try
                    {
                        using (var tx = new TransactionScope(AmbientTransation))
                        {
                            sessionImplementor.BeforeTransactionCompletion(null);
                            if (sessionImplementor.FlushMode != FlushMode.Never && sessionImplementor.ConnectionManager.IsConnected)
                            {
                                using (sessionImplementor.ConnectionManager.FlushingFromDtcTransaction)
                                {
                                    logger.Debug(string.Format("[session-id={0}] Flushing from Dtc Transaction", sessionImplementor.SessionId));
                                    sessionImplementor.Flush();
                                }
                            }
                            logger.Debug("prepared for DTC transaction");

                            tx.Complete();
                        }
                        preparingEnlistment.Prepared();
                    }
                    catch (Exception exception)
                    {
                        logger.Error("DTC transaction prepre phase failed", exception);
                        preparingEnlistment.ForceRollback(exception);
                    }
                }
            }
Example #7
0
        /// <summary>
        /// Notifies an enlisted object that a transaction is being prepared
        /// for commitment.
        /// </summary>
        /// <param name="preparingEnlistment">
        /// A <see cref="T:System.Transactions.PreparingEnlistment" /> object
        /// used to send a response to the transaction manager.
        /// </param>
        public void Prepare(PreparingEnlistment preparingEnlistment)
        {
            try
            {
#if DEBUG
                Console.WriteLine(
                    "{0}.Prepare(...) (try) - {1}",
                    this.GetType(),
                    this.managedPath);
#endif

                this.ManagedFileStream = this.OnPrepareFileStream(this.managedPath);

                preparingEnlistment.Prepared();
            }
            catch (Exception e)
            {
#if DEBUG
                Console.WriteLine(
                    "{0}.Prepare(...) (catch) - {1}",
                    this.GetType(),
                    this.managedPath);
#endif
                // Rollback() is not called on a resource manager
                // if its Prepare() method votes for rollback.
                if (!this.disposed)
                {
                    this.OnRollback();
                }

                preparingEnlistment.ForceRollback(e);
            }
        }
Example #8
0
        public virtual void Prepare(PreparingEnlistment preparingEnlistment)
        {
            try
            {
                if (this.dataAccessObjectDataContext != null)
                {
                    this.dataAccessObjectDataContext.Commit(this, false);
                }

                preparingEnlistment.Prepared();
            }
            catch (TransactionAbortedException)
            {
                throw;
            }
            catch (Exception e)
            {
                foreach (var persistenceTransactionContext in this.persistenceTransactionContextsBySqlDatabaseContexts.Values)
                {
                    persistenceTransactionContext.sqlDatabaseCommandsContext.Rollback();
                }

                preparingEnlistment.ForceRollback(e);

                Dispose();
            }
        }
 public void Prepare(PreparingEnlistment preparingEnlistment)
 {
     if (_transaction != null && !_transaction.HasMutations)
     {
         // In the case where our resource manager doesn't have any mutations, it was a read,
         // which we will no-op and allow through even if it was a two phase commit.
         // This allows cases such as nested transactions where the inner transaction is a readonly
         // timestamp bound read and doesn't have anything to commit.
         Logger.Debug(() => "Received a PREPARE for a two phase commit but without changes. This is allowed.");
         preparingEnlistment.Prepared();
         return;
     }
     Logger.Warn(() => "Received a call to Prepare, which indicates two phase commit inside a transaction scope. This is currently not supported in Spanner.");
     try
     {
         preparingEnlistment.ForceRollback(new NotSupportedException(
                                               "Spanner only supports single phase commit (Prepare not supported)."
                                               + " This error can happen when attempting to use multiple transaction resources but may also happen for"
                                               + " other reasons that cause a Transaction to use two-phase commit."));
     }
     finally
     {
         // We've forced a rollback, but the expectation is that *this* resource
         // manager won't have done anything yet, given that we've "failed" to prepare.
         // Therefore we need to clean ourselves up. The other resource managers that have already
         // been prepared will be cleaned up by the transaction manager.
         Dispose();
     }
 }
        public void Prepare(PreparingEnlistment preparingEnlistment)
        {
            uint method = 0x528;

            this.TrEntry(method, new object[] { preparingEnlistment });
            preparingEnlistment.ForceRollback();
            base.TrExit(method);
        }
Example #11
0
            /// <summary>
            /// Prepare the session for the transaction commit. Run
            /// <see cref="ISessionImplementor.BeforeTransactionCompletion(ITransaction)"/> for the session and for
            /// <see cref="ConnectionManager.DependentSessions"/> if any. <see cref="Lock"/> the context
            /// before signaling it is done, or before rollback in case of failure.
            /// </summary>
            /// <param name="preparingEnlistment">The object for notifying the prepare phase outcome.</param>
            public virtual void Prepare(PreparingEnlistment preparingEnlistment)
            {
                _preparing = true;
                using (_session.BeginContext())
                {
                    try
                    {
                        using (_session.ConnectionManager.BeginProcessingFromSystemTransaction(_useConnectionOnSystemTransactionPrepare))
                        {
                            if (_useConnectionOnSystemTransactionPrepare)
                            {
                                // Ensure any newly acquired connection gets enlisted in the transaction. When distributed,
                                // this code runs from another thread and we cannot rely on Transaction.Current.
                                using (var tx = new TransactionScope(EnlistedTransaction))
                                {
                                    // Required when both connection auto-enlistment and session auto-enlistment are disabled.
                                    _session.JoinTransaction();
                                    _session.BeforeTransactionCompletion(null);
                                    foreach (var dependentSession in _session.ConnectionManager.DependentSessions)
                                    {
                                        dependentSession.BeforeTransactionCompletion(null);
                                    }

                                    tx.Complete();
                                }
                            }
                            else
                            {
                                _session.BeforeTransactionCompletion(null);
                                foreach (var dependentSession in _session.ConnectionManager.DependentSessions)
                                {
                                    dependentSession.BeforeTransactionCompletion(null);
                                }
                            }
                        }
                        // Lock the session to ensure second phase gets done before the session is used by code following
                        // the transaction scope disposal.
                        Lock();

                        _logger.Debug("Prepared for system transaction");
                        _preparing = false;
                        preparingEnlistment.Prepared();
                    }
                    catch (Exception exception)
                    {
                        _preparing = false;
                        _logger.Error(exception, "System transaction prepare phase failed");
                        try
                        {
                            CompleteTransaction(false);
                        }
                        finally
                        {
                            preparingEnlistment.ForceRollback(exception);
                        }
                    }
                }
            }
    public void Prepare ( PreparingEnlistment preparingEnlistment )
    {
        resource.NumPrepare++;
        if ( resource.IgnorePrepare )
            return;

        if ( resource.FailPrepare )
        {
            if (resource.FailWithException)
                preparingEnlistment.ForceRollback ( new NotSupportedException () );
            else
                preparingEnlistment.ForceRollback ();
        }
        else
        {
            preparingEnlistment.Prepared ();
        }
    }
        public void Prepare(PreparingEnlistment preparingEnlistment)
        {
            Console.WriteLine("PREPARE - VolatileResource");
            if (throwIt && ++errorCount < 2)
            {
                throw new ApplicationException("simulating resource failure");
            }

            preparingEnlistment.ForceRollback();
        }
Example #14
0
 public void Prepare(PreparingEnlistment preparingEnlistment)
 {
     this.CheckDisposed();
     if (!this._transaction.IsValid(false))
     {
         preparingEnlistment.ForceRollback();
         return;
     }
     preparingEnlistment.Prepared();
 }
Example #15
0
 public void Prepare(PreparingEnlistment preparingEnlistment)
 {
     try
     {
         preparingEnlistment.Prepared();
     }
     catch (Exception ex)
     {
         preparingEnlistment.ForceRollback(ex);
     }
 }
Example #16
0
 public void Prepare(PreparingEnlistment preparingEnlistment)
 {
     if (_unitOfWork.KeepAlive())
     {
         preparingEnlistment.Prepared();
     }
     else
     {
         preparingEnlistment.ForceRollback();
     }
 }
 void IEnlistmentNotification.Prepare(PreparingEnlistment preparingEnlistment)
 {
     if (!_transaction.NotifyPrepare())
     {
         preparingEnlistment.ForceRollback();
     }
     else
     {
         preparingEnlistment.Prepared();
     }
 }
Example #18
0
 public void Prepare(PreparingEnlistment preparingEnlistment)
 {
     if (RandomRollback && rand.Next(0, 10) > 7)
     {
         preparingEnlistment.ForceRollback();
     }
     else
     {
         preparingEnlistment.Prepared();
     }
 }
Example #19
0
 public void Prepare(PreparingEnlistment preparingEnlistment)
 {
     if (_transaction.IsValid(false) == false)
     {
         preparingEnlistment.ForceRollback();
     }
     else
     {
         preparingEnlistment.Prepared();
     }
 }
 public void Prepare(PreparingEnlistment preparingEnlistment)
 {
     if (_ThrowIt)
     {
         preparingEnlistment.ForceRollback(new ApplicationException("this one went astray"));
     }
     else
     {
         preparingEnlistment.Prepared();
     }
 }
    public void Prepare(PreparingEnlistment preparingEnlistment)
    {
        Console.WriteLine("Prepare notification received");

        //Perform transactional work

        //If work finished correctly, reply prepared
        preparingEnlistment.Prepared();

        // otherwise, do a ForceRollback
        preparingEnlistment.ForceRollback();
    }
Example #22
0
 /// <summary>
 /// Notifies an enlisted object that a transaction is being prepared for
 /// commitment.
 /// </summary>
 /// <param name="preparingEnlistment">
 /// A <see cref="T:System.Transactions.PreparingEnlistment"></see> object
 /// used to send a response to the transaction manager.</param>
 void IEnlistmentNotification.Prepare(PreparingEnlistment preparingEnlistment)
 {
     if (m_dbTransaction.m_valid)
     {
         m_dbTransaction.Connection.Session.PrepareCommit();
         preparingEnlistment.Prepared();
     }
     else
     {
         preparingEnlistment.ForceRollback();
     }
 } 
Example #23
0
 public void Prepare(PreparingEnlistment preparingEnlistment)
 {
     try
     {
         PrepareAction();
         preparingEnlistment.Prepared();
     }
     catch
     {
         preparingEnlistment.ForceRollback();
     }
 }
 //Don't throw an exception here. Instead call ForceRollback()
 public void Prepare(PreparingEnlistment preparingEnlistment)
 {
     try
     {
         Execute();
         preparingEnlistment.Prepared();
     }
     catch (Exception e)
     {
         preparingEnlistment.ForceRollback(e);
     }
 }
Example #25
0
 public void Prepare(PreparingEnlistment preparingEnlistment)
 {
     try
     {
         // Nothing to do
         preparingEnlistment.Prepared();
     }
     catch (Exception e)
     {
         preparingEnlistment.ForceRollback(e);
     }
 }
Example #26
0
 public void Prepare(PreparingEnlistment preparingEnlistment)
 {
     try
     {
         Neo4jRestTransaction.DoKeepAlive(transactionExecutionEnvironment);
         preparingEnlistment.Prepared();
     }
     catch (Exception e)
     {
         preparingEnlistment.ForceRollback(e);
     }
 }
 public void Prepare(PreparingEnlistment preparingEnlistment)
 {
     if ((this.channel.State == CommunicationState.Opened) && (this.channel.InternalPendingItems > 0))
     {
         Exception e = DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(System.ServiceModel.SR.GetString("MsmqSessionChannelsMustBeClosed")));
         preparingEnlistment.ForceRollback(e);
         this.channel.Fault();
     }
     else
     {
         preparingEnlistment.Done();
     }
 }
 public void Prepare(PreparingEnlistment preparingEnlistment)
 {
     Assert.AreNotEqual(thread, Thread.CurrentThread.ManagedThreadId);
     if (shouldRollBack)
     {
         log.Debug(">>>>Force Rollback<<<<<");
         preparingEnlistment.ForceRollback();
     }
     else
     {
         preparingEnlistment.Prepared();
     }
 }
Example #29
0
 public void Prepare(PreparingEnlistment preparingEnlistment)
 {
     try
     {
         _transaction.IsValid();
     }
     catch (Exception e)
     {
         preparingEnlistment.ForceRollback(e);
         return;
     }
     preparingEnlistment.Prepared();
 }
 public void Prepare(PreparingEnlistment preparingEnlistment)
 {
     if (this.channel.State != CommunicationState.Closed)
     {
         this.channel.Fault();
         Exception e = DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(System.ServiceModel.SR.GetString("MsmqSessionChannelsMustBeClosed")));
         preparingEnlistment.ForceRollback(e);
     }
     else
     {
         preparingEnlistment.Prepared();
     }
 }
Example #31
0
 public void Prepare(PreparingEnlistment preparingEnlistment)
 {
     switch (_phase1Vote)
     {
         case Phase1Vote.Prepared:
             {
                 preparingEnlistment.Prepared();
                 break;
             }
         case Phase1Vote.ForceRollback:
             {
                 preparingEnlistment.ForceRollback();
                 break;
             }
         case Phase1Vote.Done:
             {
                 preparingEnlistment.Done();
                 break;
             }
     }
 }
Example #32
0
 public void Prepare(PreparingEnlistment preparingEnlistment)
 {
     switch (_phase1Vote)
     {
         case Phase1Vote.Prepared:
             {
                 if (_volatileEnlistDuringPrepare)
                 {
                     TestEnlistment newVol = new TestEnlistment(_phase1Vote, _expectedOutcome);
                     try
                     {
                         _txToEnlist.EnlistVolatile(newVol, EnlistmentOptions.None);
                         Assert.Equal(_expectEnlistToSucceed, true);
                     }
                     catch (Exception)
                     {
                         Assert.Equal(_expectEnlistToSucceed, false);
                     }
                 }
                 preparingEnlistment.Prepared();
                 break;
             }
         case Phase1Vote.ForceRollback:
             {
                 if (_outcomeReceived != null)
                 {
                     _outcomeReceived.Set();
                 }
                 preparingEnlistment.ForceRollback();
                 break;
             }
         case Phase1Vote.Done:
             {
                 if (_outcomeReceived != null)
                 {
                     _outcomeReceived.Set();
                 }
                 preparingEnlistment.Done();
                 break;
             }
     }
 }
Example #33
0
            public void Prepare(PreparingEnlistment preparingEnlistment)
            {
                if (_enlistDuringPrepare)
                {
                    Trace(string.Format("MyEnlistment.Prepare - attempting another enlistment with options {0}", _enlistOptions.ToString()));
                    try
                    {
                        MyEnlistment enlist2 = new MyEnlistment(
                            _secondEnlistmentCompleted,
                            /*votePrepared=*/ true,
                            /*enlistDuringPrepare=*/ false,
                            _enlistOptions);
                        this.TransactionToEnlist.EnlistVolatile(enlist2, _enlistOptions);
                        if (!_expectSuccessfulEnlist)
                        {
                            // Force rollback of the transaction because the second enlistment was unsuccessful.
                            Trace("MyEnlistment.Prepare - Force Rollback because second enlistment succeeded unexpectedly");
                            _aborted = true;
                            _outcomeReceived.Set();
                            preparingEnlistment.ForceRollback(new Exception("MyEnlistment voted ForceRollback"));
                            return;
                        }
                    }
                    catch (Exception ex)
                    {
                        if (_expectSuccessfulEnlist)
                        {
                            Trace(string.Format("MyEnlistment.Prepare - Force Rollback because second enlistment failed unexpectedly - {0}; {1}", ex.GetType().ToString(), ex.ToString()));
                            // Force rollback of the transaction because the second enlistment was unsuccessful.
                            _aborted = true;
                            _outcomeReceived.Set();
                            preparingEnlistment.ForceRollback(new Exception("MyEnlistment voted ForceRollback"));
                            return;
                        }
                    }
                }

                if (_votePrepared)
                {
                    Trace("MyEnlistment.Prepare voting Prepared");
                    preparingEnlistment.Prepared();
                }
                else
                {
                    Trace("MyEnlistment.Prepare - Force Rollback");
                    _aborted = true;
                    _outcomeReceived.Set();
                    preparingEnlistment.ForceRollback(new Exception("MyEnlistment voted ForceRollback"));
                }
            }
Example #34
0
        public void Prepare(PreparingEnlistment preparingEnlistment)
        {
            resource.NumPrepare++;
            if (resource.IgnorePrepare)
                return;

            if (resource.FailPrepare)
            {
                if (resource.FailWithException)
                    preparingEnlistment.ForceRollback(resource.ThrowThisException ?? new NotSupportedException());
                else
                    preparingEnlistment.ForceRollback();
            }
            else
            {
                preparingEnlistment.Prepared();
            }
        }
Example #35
0
        public void Prepare(PreparingEnlistment preparingEnlistment)
        {
            try
            {
                dtcControlEvent.Reset();

                Tracer.Debug("Prepare notification received for TX id: " + this.transactionId);

                BeforeEnd();

                // Before sending the request to the broker, log the recovery bits, if
                // this fails we can't prepare and the TX should be rolled back.
                RecoveryLogger.LogRecoveryInfo(this.transactionId as XATransactionId,
                                               preparingEnlistment.RecoveryInformation());

                // Inform the broker that work on the XA'sh TX Branch is complete.
                TransactionInfo info = new TransactionInfo();
                info.ConnectionId = this.connection.ConnectionId;
                info.TransactionId = this.transactionId;
                info.Type = (int) TransactionType.End;

                this.connection.CheckConnected();
                this.connection.SyncRequest(info);

                // Prepare the Transaction for commit.
                info.Type = (int) TransactionType.Prepare;
                IntegerResponse response = (IntegerResponse) this.connection.SyncRequest(info);
                if(response.Result == XA_READONLY)
                {
                    Tracer.Debug("Transaction Prepare done and doesn't need a commit, TX id: " + this.transactionId);

                    this.transactionId = null;
                    this.currentEnlistment = null;

                    // Read Only means there's nothing to recover because there was no
                    // change on the broker.
                    RecoveryLogger.LogRecovered(this.transactionId as XATransactionId);

                    // if server responds that nothing needs to be done, then reply prepared
                    // but clear the current state data so we appear done to the commit method.
                    preparingEnlistment.Prepared();

                    // Done so commit won't be called.
                    AfterCommit();
                }
                else
                {
                    Tracer.Debug("Transaction Prepare succeeded TX id: " + this.transactionId);

                    // If work finished correctly, reply prepared
                    preparingEnlistment.Prepared();
                }
            }
            catch(Exception ex)
            {
                Tracer.DebugFormat("Transaction[{0}] Prepare failed with error: {1}",
                                   this.transactionId, ex.Message);

                AfterRollback();
                preparingEnlistment.ForceRollback();
                try
                {
                    this.connection.OnException(ex);
                }
                catch (Exception error)
                {
                    Tracer.Error(error.ToString());
                }

                this.currentEnlistment = null;
                this.transactionId = null;
            }
            finally
            {
                this.dtcControlEvent.Set();
            }
        }